]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-4570.51.1.tar.gz macos-10134 v4570.51.1
authorApple <opensource@apple.com>
Wed, 15 Aug 2018 19:26:13 +0000 (19:26 +0000)
committerApple <opensource@apple.com>
Wed, 15 Aug 2018 19:26:13 +0000 (19:26 +0000)
571 files changed:
Makefile
README.md
bsd/bsm/audit_kevents.h
bsd/conf/files
bsd/dev/arm/cpu_in_cksum.s
bsd/dev/arm64/cpu_in_cksum.s
bsd/dev/chud/chud_process.c [deleted file]
bsd/dev/dtrace/dtrace.c
bsd/dev/dtrace/dtrace_glue.c
bsd/dev/dtrace/fbt.c
bsd/dev/dtrace/sdt.c
bsd/dev/dtrace/sdt_subr.c
bsd/dev/i386/fbt_x86.c
bsd/dev/monotonic.c
bsd/kern/bsd_init.c
bsd/kern/kdebug.c
bsd/kern/kern_authorization.c
bsd/kern/kern_cs.c
bsd/kern/kern_descrip.c
bsd/kern/kern_event.c
bsd/kern/kern_exec.c
bsd/kern/kern_exit.c
bsd/kern/kern_malloc.c
bsd/kern/kern_memorystatus.c
bsd/kern/kern_mib.c
bsd/kern/kern_mman.c
bsd/kern/kern_persona.c
bsd/kern/kern_proc.c
bsd/kern/kern_shutdown.c
bsd/kern/kern_sig.c
bsd/kern/kern_sysctl.c
bsd/kern/mach_loader.c
bsd/kern/mach_loader.h
bsd/kern/policy_check.c
bsd/kern/proc_info.c
bsd/kern/pthread_shims.c
bsd/kern/subr_eventhandler.c
bsd/kern/sys_persona.c
bsd/kern/sys_work_interval.c
bsd/kern/trace_codes
bsd/kern/tty_dev.c
bsd/kern/tty_ptmx.c
bsd/kern/uipc_mbuf.c
bsd/kern/uipc_mbuf2.c
bsd/kern/uipc_socket.c
bsd/kern/uipc_socket2.c
bsd/libkern/crc16.c
bsd/libkern/libkern.h
bsd/man/man2/fcntl.2
bsd/man/man2/fs_snapshot_create.2
bsd/man/man2/getattrlistbulk.2
bsd/man/man2/getdirentries.2
bsd/miscfs/specfs/spec_vnops.c
bsd/net/Makefile
bsd/net/bpf.c
bsd/net/classq/classq_fq_codel.c
bsd/net/classq/classq_fq_codel.h
bsd/net/classq/classq_subr.c
bsd/net/classq/if_classq.h
bsd/net/dlil.c
bsd/net/dlil.h
bsd/net/if.c
bsd/net/if.h
bsd/net/if_fake.c
bsd/net/if_fake_var.h
bsd/net/if_gif.c
bsd/net/if_ipsec.c
bsd/net/if_ports_used.c [new file with mode: 0644]
bsd/net/if_ports_used.h [new file with mode: 0644]
bsd/net/if_stf.c
bsd/net/if_utun.c
bsd/net/if_var.h
bsd/net/kpi_interface.c
bsd/net/necp.c
bsd/net/necp.h
bsd/net/necp_client.c
bsd/net/net_stubs.c
bsd/net/network_agent.c
bsd/net/ntstat.c
bsd/net/pf.c
bsd/net/pktsched/pktsched_tcq.c
bsd/net/route.c
bsd/net/route.h
bsd/net/rtsock.c
bsd/netinet/in_gif.c
bsd/netinet/in_pcb.c
bsd/netinet/in_pcblist.c
bsd/netinet/in_tclass.c
bsd/netinet/ip_divert.c
bsd/netinet/ip_icmp.c
bsd/netinet/ip_input.c
bsd/netinet/kpi_ipfilter.c
bsd/netinet/mp_pcb.c
bsd/netinet/mptcp.c
bsd/netinet/mptcp_opt.c
bsd/netinet/mptcp_subr.c
bsd/netinet/mptcp_timer.c
bsd/netinet/mptcp_usrreq.c
bsd/netinet/mptcp_var.h
bsd/netinet/raw_ip.c
bsd/netinet/tcp.h
bsd/netinet/tcp_cache.c
bsd/netinet/tcp_input.c
bsd/netinet/tcp_output.c
bsd/netinet/tcp_subr.c
bsd/netinet/tcp_timer.c
bsd/netinet/tcp_usrreq.c
bsd/netinet/udp_usrreq.c
bsd/netinet6/icmp6.c
bsd/netinet6/in6_pcb.c
bsd/netinet6/in6_src.c
bsd/netinet6/ip6_input.c
bsd/netinet6/ipsec.c
bsd/netinet6/nd6.c
bsd/netinet6/nd6_nbr.c
bsd/netinet6/nd6_rtr.c
bsd/netinet6/raw_ip6.c
bsd/netinet6/udp6_output.c
bsd/netkey/key.c
bsd/nfs/krpc_subr.c
bsd/nfs/nfs_boot.c
bsd/nfs/nfs_socket.c
bsd/nfs/nfs_vfsops.c
bsd/security/audit/audit_bsd.c
bsd/sys/bsdtask_info.h
bsd/sys/cdefs.h
bsd/sys/codesign.h
bsd/sys/cprotect.h
bsd/sys/dtrace_glue.h
bsd/sys/eventhandler.h
bsd/sys/kdebug.h
bsd/sys/mbuf.h
bsd/sys/persona.h
bsd/sys/priv.h
bsd/sys/proc.h
bsd/sys/proc_info.h
bsd/sys/proc_internal.h
bsd/sys/reason.h
bsd/sys/socket.h
bsd/sys/socketvar.h
bsd/sys/sockio.h
bsd/sys/sysctl.h
bsd/sys/syslog.h
bsd/sys/systm.h
bsd/sys/work_interval.h
bsd/vfs/vfs_cluster.c
bsd/vfs/vfs_cprotect.c
bsd/vfs/vfs_subr.c
bsd/vfs/vfs_syscalls.c
bsd/vm/vm_unix.c
config/IOKit.exports
config/IOKit.x86_64.exports
config/Libkern.exports
config/MASTER.arm
config/MASTER.arm64
config/Mach.exports
config/MasterVersion
config/Private.exports
config/Private.x86_64.exports
iokit/IOKit/IOBufferMemoryDescriptor.h
iokit/IOKit/IOCPU.h
iokit/IOKit/IOCommandGate.h
iokit/IOKit/IOFilterInterruptEventSource.h
iokit/IOKit/IOHibernatePrivate.h
iokit/IOKit/IOInterruptController.h
iokit/IOKit/IOInterruptEventSource.h
iokit/IOKit/IOKitKeysPrivate.h
iokit/IOKit/IOKitServer.h
iokit/IOKit/IONVRAM.h
iokit/IOKit/IOPlatformExpert.h
iokit/IOKit/IOPolledInterface.h
iokit/IOKit/IOService.h
iokit/IOKit/IOTimerEventSource.h
iokit/IOKit/IOUserClient.h
iokit/IOKit/pwr_mgt/IOPM.h
iokit/IOKit/system_management/IOWatchDogTimer.h
iokit/Kernel/IOCommandQueue.cpp
iokit/Kernel/IOHibernateIO.cpp
iokit/Kernel/IOHibernateInternal.h
iokit/Kernel/IOInterruptController.cpp
iokit/Kernel/IOKitKernelInternal.h
iokit/Kernel/IOMemoryDescriptor.cpp
iokit/Kernel/IONVRAM.cpp
iokit/Kernel/IOPMrootDomain.cpp
iokit/Kernel/IOPlatformExpert.cpp
iokit/Kernel/IOPolledInterface.cpp
iokit/Kernel/IORangeAllocator.cpp
iokit/Kernel/IOService.cpp
iokit/Kernel/IOUserClient.cpp
iokit/Tests/Tests.cpp
iokit/bsddev/IOKitBSDInit.cpp
libkdd/kcdata.h
libkdd/kcdtypes.c
libkdd/kdd.framework/Info.plist [new file with mode: 0644]
libkdd/kdd.framework/module.modulemap [new file with mode: 0644]
libkdd/kdd.frameworkTests/Info.plist [new file with mode: 0644]
libkdd/kdd.h
libkdd/kdd.xcodeproj/project.pbxproj
libkdd/tests/Tests.swift
libkdd/tests/stackshot-sample-delta-thread-policy [new file with mode: 0644]
libkdd/tests/stackshot-sample-delta-thread-policy.plist.gz [new file with mode: 0644]
libkern/c++/OSMetaClass.cpp
libkern/c++/OSSerializeBinary.cpp
libkern/c++/OSString.cpp
libkern/c++/OSUnserializeXML.cpp
libkern/c++/OSUnserializeXML.y
libkern/conf/Makefile.template
libkern/crypto/corecrypto_rand.c
libkern/crypto/corecrypto_sha2.c
libkern/crypto/register_crypto.c
libkern/libkern/c++/OSKext.h
libkern/libkern/c++/OSMetaClass.h
libkern/libkern/crypto/Makefile
libkern/libkern/crypto/rand.h
libkern/libkern/kext_panic_report.h
libsa/bootstrap.cpp
libsyscall/wrappers/libproc/libproc.c
libsyscall/wrappers/libproc/libproc.h
libsyscall/wrappers/work_interval.c
makedefs/MakeInc.def
makedefs/MakeInc.top
osfmk/arm/cpu_common.c
osfmk/arm/cpu_data_internal.h
osfmk/arm/cpu_internal.h
osfmk/arm/locore.s
osfmk/arm/machine_routines.c
osfmk/arm/machine_routines.h
osfmk/arm/machine_routines_common.c
osfmk/arm/model_dep.c
osfmk/arm/pmap.c
osfmk/arm/proc_reg.h
osfmk/arm/trap.c
osfmk/arm/trap.h
osfmk/arm64/caches_asm.s
osfmk/arm64/locore.s
osfmk/arm64/machine_routines.c
osfmk/arm64/pcb.c
osfmk/arm64/platform_tests.c
osfmk/arm64/proc_reg.h
osfmk/arm64/sleh.c
osfmk/arm64/start.s
osfmk/atm/atm.c
osfmk/chud/chud_cpu.c [deleted file]
osfmk/chud/chud_glue.c [deleted file]
osfmk/chud/chud_memory.c [deleted file]
osfmk/chud/chud_osfmk_callback.c [deleted file]
osfmk/chud/chud_thread.c [deleted file]
osfmk/chud/chud_thread.h [deleted file]
osfmk/chud/chud_xnu.h [deleted file]
osfmk/chud/chud_xnu_glue.h [deleted file]
osfmk/chud/chud_xnu_private.h [deleted file]
osfmk/chud/i386/chud_cpu_i386.c [deleted file]
osfmk/chud/i386/chud_osfmk_callback_i386.c [deleted file]
osfmk/chud/i386/chud_thread_i386.c [deleted file]
osfmk/chud/i386/chud_xnu_glue.h [deleted file]
osfmk/chud/i386/chud_xnu_private.h [deleted file]
osfmk/conf/Makefile.template
osfmk/conf/files
osfmk/conf/files.arm
osfmk/conf/files.arm64
osfmk/conf/files.x86_64
osfmk/corpses/task_corpse.h
osfmk/device/device.defs
osfmk/device/iokit_rpc.c
osfmk/i386/AT386/model_dep.c
osfmk/i386/acpi.c
osfmk/i386/bsd_i386.c
osfmk/i386/cpu_data.h
osfmk/i386/cpu_threads.c
osfmk/i386/cpu_topology.c
osfmk/i386/locks_i386.c
osfmk/i386/machine_routines.c
osfmk/i386/misc_protos.h
osfmk/i386/mp.c
osfmk/i386/mp_events.h
osfmk/i386/pcb.c
osfmk/i386/pmCPU.c
osfmk/i386/rtclock_asm.h
osfmk/i386/trap.c
osfmk/i386/trap.h
osfmk/ipc/ipc_kmsg.c
osfmk/kdp/kdp_core.c
osfmk/kdp/ml/x86_64/kdp_vm.c
osfmk/kern/Makefile
osfmk/kern/ast.h
osfmk/kern/bsd_kern.c
osfmk/kern/coalition.c
osfmk/kern/debug.c
osfmk/kern/debug.h
osfmk/kern/ipc_kobject.c
osfmk/kern/ipc_kobject.h
osfmk/kern/kalloc.c
osfmk/kern/kcdata.h
osfmk/kern/kern_cdata.c
osfmk/kern/kern_stackshot.c
osfmk/kern/kpc_common.c
osfmk/kern/machine.h
osfmk/kern/priority.c
osfmk/kern/sched_multiq.c
osfmk/kern/sched_prim.c
osfmk/kern/sched_prim.h
osfmk/kern/startup.c
osfmk/kern/syscall_subr.c
osfmk/kern/task.c
osfmk/kern/task.h
osfmk/kern/task_policy.c
osfmk/kern/thread.c
osfmk/kern/thread.h
osfmk/kern/thread_act.c
osfmk/kern/thread_policy.c
osfmk/kern/timer_call.c
osfmk/kern/work_interval.c
osfmk/kern/work_interval.h
osfmk/kern/zalloc.c
osfmk/kperf/callstack.c
osfmk/kperf/kperf_timer.c
osfmk/kperf/kperf_timer.h
osfmk/kperf/sample.h
osfmk/kperf/thread_samplers.c
osfmk/mach/Makefile
osfmk/mach/branch_predicates.h
osfmk/mach/coalition.h
osfmk/mach/host_special_ports.h
osfmk/mach/mach_host.defs
osfmk/mach/task_info.h
osfmk/mach/vm32_map.defs
osfmk/mach/vm_map.defs
osfmk/mach/vm_statistics.h
osfmk/mach_debug/mach_debug_types.defs
osfmk/mach_debug/zone_info.h
osfmk/vm/bsd_vm.c
osfmk/vm/vm32_user.c
osfmk/vm/vm_compressor.c
osfmk/vm/vm_compressor.h
osfmk/vm/vm_compressor_algorithms.c
osfmk/vm/vm_compressor_backing_store.c
osfmk/vm/vm_map.c
osfmk/vm/vm_map.h
osfmk/vm/vm_object.c
osfmk/vm/vm_object.h
osfmk/vm/vm_pageout.c
osfmk/vm/vm_protos.h
osfmk/vm/vm_purgeable.c
osfmk/vm/vm_purgeable_internal.h
osfmk/vm/vm_user.c
osfmk/x86_64/bcopy.s
osfmk/x86_64/idt64.s
osfmk/x86_64/kpc_x86.c
osfmk/x86_64/lowglobals.h
osfmk/x86_64/lowmem_vectors.c
osfmk/x86_64/pmap.c
pexpert/arm/pe_consistent_debug.c
pexpert/arm/pe_serial.c
pexpert/i386/pe_serial.c
pexpert/pexpert/AppleBoot.h
pexpert/pexpert/arm/consistent_debug.h
pexpert/pexpert/arm64/arm64_common.h
pexpert/pexpert/pexpert.h
san/Kasan_kasan.exports
san/Makefile
san/conf/Makefile.template
san/kasan-arm64.c
san/kasan-blacklist
san/kasan-blacklist-arm64
san/kasan-blacklist-dynamic [new file with mode: 0644]
san/kasan-blacklist-x86_64
san/kasan-fakestack.c
san/kasan-memintrinsics.c
san/kasan-test.c
san/kasan-x86_64.c
san/kasan.c
san/kasan.h
san/kasan_dynamic_blacklist.c
san/kasan_internal.h
san/tools/generate_dynamic_blacklist.py
san/tools/validate_blacklist.sh [new file with mode: 0755]
security/mac_policy.h
tools/lldbmacros/Makefile
tools/lldbmacros/README.md
tools/lldbmacros/kasan.py
tools/lldbmacros/kcdata.py
tools/lldbmacros/process.py
tools/lldbmacros/xnu.py
tools/lldbmacros/zonetriage.py [new file with mode: 0755]
tools/reindent.sh
tools/tests/darwintests/Makefile
tools/tests/darwintests/atm_diagnostic_flag.c [new file with mode: 0644]
tools/tests/darwintests/data_protection.c
tools/tests/darwintests/drop_priv.c [new file with mode: 0644]
tools/tests/darwintests/freebsd_waitpid_nohang.c [new file with mode: 0644]
tools/tests/darwintests/jumbo_va_spaces_28530648.c
tools/tests/darwintests/memorystatus_vm_map_fork.c [new file with mode: 0644]
tools/tests/darwintests/memorystatus_zone_test.c
tools/tests/darwintests/net_tun_pr_35136664.c [new file with mode: 0644]
tools/tests/darwintests/net_tuntests.c [new file with mode: 0644]
tools/tests/darwintests/netbsd_utimensat.c
tools/tests/darwintests/network_entitlements.plist [new file with mode: 0644]
tools/tests/darwintests/no32exec_35914211.c [new file with mode: 0644]
tools/tests/darwintests/no32exec_35914211_helper.c [new file with mode: 0644]
tools/tests/darwintests/perf_compressor.c
tools/tests/darwintests/poll_select_kevent_paired_fds.c
tools/tests/darwintests/proc_info.c
tools/tests/darwintests/proc_info_udata.c [new file with mode: 0644]
tools/tests/darwintests/settimeofday_29193041.c
tools/tests/darwintests/settimeofday_29193041_entitled.c
tools/tests/darwintests/socket_bind_35243417.c
tools/tests/darwintests/socket_bind_35685803.c [new file with mode: 0644]
tools/tests/darwintests/stackshot.m
tools/tests/darwintests/stackshot_block_owner_14362384.m
tools/tests/darwintests/task_info.c
tools/tests/darwintests/thread_group_set_32261625.c
tools/tests/darwintests/utimensat.c
tools/tests/darwintests/verify_kalloc_config.c [new file with mode: 0644]
tools/tests/darwintests/xnu_quick_test_getsetpriority.c [new file with mode: 0644]
tools/tests/libMicro/AppleReadMe [deleted file]
tools/tests/libMicro/Makefile [deleted file]
tools/tests/libMicro/Makefile.Aix [deleted file]
tools/tests/libMicro/Makefile.Darwin [deleted file]
tools/tests/libMicro/Makefile.Linux [deleted file]
tools/tests/libMicro/Makefile.SunOS [deleted file]
tools/tests/libMicro/Makefile.benchmarks [deleted file]
tools/tests/libMicro/Makefile.com [deleted file]
tools/tests/libMicro/Makefile.com.Darwin [deleted file]
tools/tests/libMicro/OPENSOLARIS.LICENSE [deleted file]
tools/tests/libMicro/README [deleted file]
tools/tests/libMicro/apple/Makefile [deleted file]
tools/tests/libMicro/apple/Makefile.Darwin [deleted file]
tools/tests/libMicro/apple/Makefile.benchmarks [deleted file]
tools/tests/libMicro/apple/Makefile.com.Darwin [deleted file]
tools/tests/libMicro/apple/create_file.c [deleted file]
tools/tests/libMicro/apple/geekbench_stdlib_write.c [deleted file]
tools/tests/libMicro/apple/getaddrinfo_host.c [deleted file]
tools/tests/libMicro/apple/getaddrinfo_port.c [deleted file]
tools/tests/libMicro/apple/getgrent.c [deleted file]
tools/tests/libMicro/apple/getgrgid.c [deleted file]
tools/tests/libMicro/apple/getgrnam.c [deleted file]
tools/tests/libMicro/apple/getppid.c [deleted file]
tools/tests/libMicro/apple/getpwent.c [deleted file]
tools/tests/libMicro/apple/getpwnam.c [deleted file]
tools/tests/libMicro/apple/getpwuid.c [deleted file]
tools/tests/libMicro/apple/lb_mmtest.c [deleted file]
tools/tests/libMicro/apple/lm_null_call.c [deleted file]
tools/tests/libMicro/apple/lmbench_bw_file_rd.c [deleted file]
tools/tests/libMicro/apple/lmbench_bw_mem.c [deleted file]
tools/tests/libMicro/apple/lmbench_bw_mmap_rd.c [deleted file]
tools/tests/libMicro/apple/lmbench_bw_unix.c [deleted file]
tools/tests/libMicro/apple/lmbench_fstat.c [deleted file]
tools/tests/libMicro/apple/lmbench_lat_ctx.c [deleted file]
tools/tests/libMicro/apple/lmbench_lat_sig_catch.c [deleted file]
tools/tests/libMicro/apple/lmbench_lat_sig_install.c [deleted file]
tools/tests/libMicro/apple/lmbench_lat_sig_prot.c [deleted file]
tools/tests/libMicro/apple/lmbench_lat_sig_send.c [deleted file]
tools/tests/libMicro/apple/lmbench_openclose.c [deleted file]
tools/tests/libMicro/apple/lmbench_read.c [deleted file]
tools/tests/libMicro/apple/lmbench_select_file.c [deleted file]
tools/tests/libMicro/apple/lmbench_select_tcp.c [deleted file]
tools/tests/libMicro/apple/lmbench_stat.c [deleted file]
tools/tests/libMicro/apple/lmbench_write.c [deleted file]
tools/tests/libMicro/apple/mbr_check_membership.c [deleted file]
tools/tests/libMicro/apple/mbr_check_service_membership.c [deleted file]
tools/tests/libMicro/apple/od_query_create_with_node.c [deleted file]
tools/tests/libMicro/apple/posix_spawn.c [deleted file]
tools/tests/libMicro/apple/posix_spawn_bin.c [deleted file]
tools/tests/libMicro/apple/trivial.c [deleted file]
tools/tests/libMicro/apple/vm_allocate.c [deleted file]
tools/tests/libMicro/atomic.c [deleted file]
tools/tests/libMicro/bench.sh [deleted file]
tools/tests/libMicro/benchDS.sh [deleted file]
tools/tests/libMicro/benchmark_fini.c [deleted file]
tools/tests/libMicro/benchmark_finibatch.c [deleted file]
tools/tests/libMicro/benchmark_finirun.c [deleted file]
tools/tests/libMicro/benchmark_finiworker.c [deleted file]
tools/tests/libMicro/benchmark_init.c [deleted file]
tools/tests/libMicro/benchmark_initbatch.c [deleted file]
tools/tests/libMicro/benchmark_initrun.c [deleted file]
tools/tests/libMicro/benchmark_initworker.c [deleted file]
tools/tests/libMicro/benchmark_optswitch.c [deleted file]
tools/tests/libMicro/benchmark_result.c [deleted file]
tools/tests/libMicro/bind.c [deleted file]
tools/tests/libMicro/cachetocache.c [deleted file]
tools/tests/libMicro/cascade_cond.c [deleted file]
tools/tests/libMicro/cascade_fcntl.c [deleted file]
tools/tests/libMicro/cascade_flock.c [deleted file]
tools/tests/libMicro/cascade_lockf.c [deleted file]
tools/tests/libMicro/cascade_mutex.c [deleted file]
tools/tests/libMicro/chdir.c [deleted file]
tools/tests/libMicro/close.c [deleted file]
tools/tests/libMicro/close_tcp.c [deleted file]
tools/tests/libMicro/connection.c [deleted file]
tools/tests/libMicro/coreos_bench.sh [deleted file]
tools/tests/libMicro/create_stuff.sh [deleted file]
tools/tests/libMicro/dup.c [deleted file]
tools/tests/libMicro/elided.c [deleted file]
tools/tests/libMicro/embd_bench.sh [deleted file]
tools/tests/libMicro/exec.c [deleted file]
tools/tests/libMicro/exec_bin.c [deleted file]
tools/tests/libMicro/exit.c [deleted file]
tools/tests/libMicro/exp.c [deleted file]
tools/tests/libMicro/fcntl.c [deleted file]
tools/tests/libMicro/fcntl_ndelay.c [deleted file]
tools/tests/libMicro/file_lock.c [deleted file]
tools/tests/libMicro/fork.c [deleted file]
tools/tests/libMicro/getcontext.c [deleted file]
tools/tests/libMicro/getenv.c [deleted file]
tools/tests/libMicro/getpeername.c [deleted file]
tools/tests/libMicro/getpid.c [deleted file]
tools/tests/libMicro/getrusage.c [deleted file]
tools/tests/libMicro/getsockname.c [deleted file]
tools/tests/libMicro/gettimeofday.c [deleted file]
tools/tests/libMicro/isatty.c [deleted file]
tools/tests/libMicro/libmicro.c [deleted file]
tools/tests/libMicro/libmicro.h [deleted file]
tools/tests/libMicro/libmicro_main.c [deleted file]
tools/tests/libMicro/listen.c [deleted file]
tools/tests/libMicro/localtime_r.c [deleted file]
tools/tests/libMicro/log.c [deleted file]
tools/tests/libMicro/longjmp.c [deleted file]
tools/tests/libMicro/lrand48.c [deleted file]
tools/tests/libMicro/lseek.c [deleted file]
tools/tests/libMicro/malloc.c [deleted file]
tools/tests/libMicro/memcpy.c [deleted file]
tools/tests/libMicro/memmove.c [deleted file]
tools/tests/libMicro/memrand.c [deleted file]
tools/tests/libMicro/memset.c [deleted file]
tools/tests/libMicro/mk_tarball [deleted file]
tools/tests/libMicro/mktime.c [deleted file]
tools/tests/libMicro/mmap.c [deleted file]
tools/tests/libMicro/mprotect.c [deleted file]
tools/tests/libMicro/msync.c [deleted file]
tools/tests/libMicro/multiview.sh [deleted file]
tools/tests/libMicro/munmap.c [deleted file]
tools/tests/libMicro/mutex.c [deleted file]
tools/tests/libMicro/nop.c [deleted file]
tools/tests/libMicro/od_account_create.sh [deleted file]
tools/tests/libMicro/od_account_delete.sh [deleted file]
tools/tests/libMicro/open.c [deleted file]
tools/tests/libMicro/pipe.c [deleted file]
tools/tests/libMicro/poll.c [deleted file]
tools/tests/libMicro/pread.c [deleted file]
tools/tests/libMicro/pthread_create.c [deleted file]
tools/tests/libMicro/pwrite.c [deleted file]
tools/tests/libMicro/read.c [deleted file]
tools/tests/libMicro/realpath.c [deleted file]
tools/tests/libMicro/recurse.c [deleted file]
tools/tests/libMicro/recurse2.c [deleted file]
tools/tests/libMicro/select.c [deleted file]
tools/tests/libMicro/semop.c [deleted file]
tools/tests/libMicro/setcontext.c [deleted file]
tools/tests/libMicro/setsockopt.c [deleted file]
tools/tests/libMicro/sigaction.c [deleted file]
tools/tests/libMicro/siglongjmp.c [deleted file]
tools/tests/libMicro/signal.c [deleted file]
tools/tests/libMicro/sigprocmask.c [deleted file]
tools/tests/libMicro/socket.c [deleted file]
tools/tests/libMicro/socketpair.c [deleted file]
tools/tests/libMicro/stat.c [deleted file]
tools/tests/libMicro/strcasecmp.c [deleted file]
tools/tests/libMicro/strchr.c [deleted file]
tools/tests/libMicro/strcmp.c [deleted file]
tools/tests/libMicro/strcpy.c [deleted file]
tools/tests/libMicro/strftime.c [deleted file]
tools/tests/libMicro/strlen.c [deleted file]
tools/tests/libMicro/strtol.c [deleted file]
tools/tests/libMicro/system.c [deleted file]
tools/tests/libMicro/tattle.c [deleted file]
tools/tests/libMicro/time.c [deleted file]
tools/tests/libMicro/times.c [deleted file]
tools/tests/libMicro/wrapper.sh [deleted file]
tools/tests/libMicro/write.c [deleted file]
tools/tests/libMicro/writev.c [deleted file]
tools/trace/bridgetime.lua [new file with mode: 0755]

index fa9f3913296b9986e8b698f83279fcc1410d8401..1660223f5d5a0448a921997c57a5b8e5304c8a05 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -238,7 +238,7 @@ endif # CURRENT_BUILD_CONFIG
 
 endif # all other RC_ProjectName
 
-installhdrs_libkdd install_libkdd:
+installapi_libkdd installhdrs_libkdd install_libkdd:
        cd libkdd; \
                xcodebuild -target libkdd $(subst _libkdd,,$@)  \
                        "SRCROOT=$(SRCROOT)/libkdd"             \
@@ -248,6 +248,16 @@ installhdrs_libkdd install_libkdd:
                        "SDKROOT=$(SDKROOT)"
 
 
+installapi_libkdd_host installhdrs_libkdd_host install_libkdd_host:
+       cd libkdd; \
+               xcodebuild -target kdd.framework $(subst _libkdd_host,,$@)      \
+                       "SRCROOT=$(SRCROOT)/libkdd"             \
+                       "OBJROOT=$(OBJROOT)"                    \
+                       "SYMROOT=$(SYMROOT)"                    \
+                       "DSTROOT=$(DSTROOT)"                    \
+                       "SDKROOT=$(SDKROOT)"
+
+
 # "xnu_tests" and "testbots" are targets that can be invoked via a standalone
 # "make xnu_tests" or via buildit/XBS with the RC_ProjectName=xnu_tests.
 # Define the target here in the outermost scope of the initial Makefile
index b285c1a6add7f691414cd1f9002b6557c4c10afb..dc1bbbae6aefe2ed7b421f7f97aa9a87ee08d482 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
 What is XNU?
 ===========
 
-XNU kernel is part of the Darwin operating system for use in OS X and iOS operating systems. XNU is an acronym for XNU is Not Unix.
+XNU kernel is part of the Darwin operating system for use in macOS and iOS operating systems. XNU is an acronym for X is Not Unix.
 XNU is a hybrid kernel combining the Mach kernel developed at Carnegie Mellon University with components from FreeBSD and C++ API for writing drivers called IOKit.
-XNU runs on I386, X86_64 for both single processor and multi-processor configurations.
+XNU runs on x86_64 for both single processor and multi-processor configurations.
 
 XNU Source Tree
 ===============
@@ -35,9 +35,9 @@ Here is the syntax:
 
 Where:
 
-  * \<sdkroot>: path to MacOS SDK on disk. (defaults to `/`)
+  * \<sdkroot>: path to macOS SDK on disk. (defaults to `/`)
   * \<variant>: can be `debug`, `development`, `release`, `profile` and configures compilation flags and asserts throughout kernel code.
-  * \<arch>   : can be valid arch to build for. (E.g. `i386` or `X86_64`)
+  * \<arch>   : can be valid arch to build for. (E.g. `X86_64`)
 
 To build a kernel for the same architecture as running OS, just type
 
@@ -69,7 +69,7 @@ Building FAT kernel binary
 
 Define architectures in your environment or when running a make command.
 
-    $ make ARCH_CONFIGS="I386 X86_64" exporthdrs all
+    $ make ARCH_CONFIGS="X86_64" exporthdrs all
 
 Other makefile options
 ----------------------
index cd7142d60bf45d2ab1b6fbc36163911938d40bd8..391425f912c57316c39f704087f0fa501b0fe259 100644 (file)
 #define        AUE_BSDTHREADCREATE     AUE_NULL
 #define        AUE_BSDTHREADTERMINATE  AUE_NULL
 #define        AUE_BSDTHREADREGISTER   AUE_NULL
-#define        AUE_CHUD                AUE_NULL
 #define        AUE_CSOPS               AUE_NULL
 #define        AUE_DUP                 AUE_NULL
 #define        AUE_FDATASYNC           AUE_NULL
index 104c577ef69417829856d2cad9d817b04ffd4c05..4bf42f392f08a9a13ebe12ce49d67f5b2eb8c5f0 100644 (file)
@@ -217,6 +217,7 @@ bsd/net/ntstat.c                    optional networking
 bsd/net/net_perf.c                     optional networking
 bsd/net/if_gif.c                       optional gif
 bsd/net/if_stf.c                       optional stf
+bsd/net/if_ports_used.c                        optional networking
 bsd/net/kpi_interface.c                optional networking
 bsd/net/kpi_protocol.c         optional networking
 bsd/net/kpi_interfacefilter.c  optional networking
@@ -488,8 +489,6 @@ bsd/uxkern/ux_exception.c           standard
 bsd/conf/param.c                       standard
 ./ioconf.c                             standard
 
-bsd/dev/chud/chud_process.c            standard
-
 bsd/kern/imageboot.c                   optional config_imageboot
 
 osfmk/kperf/kperfbsd.c                 optional kperf
index 28f6481836152cb95514afc166baf59d5381da74..e819fd62554dbf0888e151412c83d670b19070c0 100644 (file)
@@ -1,12 +1,29 @@
 /*
- * Copyright (c) 2009-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2018 Apple Inc. All rights reserved.
  *
- * This document is the property of Apple Inc.
- * It is considered confidential and proprietary.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * This document may not be reproduced or transmitted in any form,
- * in whole or in part, without the express written permission of
- * Apple Inc.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 /*     $NetBSD: cpu_in_cksum.S,v 1.2 2008/01/27 16:58:05 chris Exp $   */
index b01b27172018c649e55587f2bd6f6e43b847bfb6..00a00c6678942aed9d9a94a4c4d493324025317a 100644 (file)
@@ -1,12 +1,29 @@
 /*
- * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2018 Apple Inc. All rights reserved.
  *
- * This document is the property of Apple Inc.
- * It is considered confidential and proprietary.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * This document may not be reproduced or transmitted in any form,
- * in whole or in part, without the express written permission of
- * Apple Inc.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 /* 
diff --git a/bsd/dev/chud/chud_process.c b/bsd/dev/chud/chud_process.c
deleted file mode 100644 (file)
index f719872..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/systm.h>
-#include <sys/proc_internal.h>
-#include <sys/vnode_internal.h> // vn_getpath()
-#include <kern/task.h>
-#include <sys/user.h>
-
-int    chudxnu_current_pid(void);
-
index 75fc4d38d6980a92ded8d118fc907e2ebf73cf40..587a8b43860f6a6de3c73868e66fd94de6e96520 100644 (file)
 #include <machine/monotonic.h>
 #endif /* MONOTONIC */
 
+#include <IOKit/IOPlatformExpert.h>
+
 #include <kern/cpu_data.h>
 extern uint32_t pmap_find_phys(void *, uint64_t);
 extern boolean_t pmap_valid_page(uint32_t);
@@ -12155,57 +12157,61 @@ dtrace_dof_copyin_from_proc(proc_t* p, user_addr_t uarg, int *errp)
        return (dof);
 }
 
+static void
+dtrace_dof_destroy(dof_hdr_t *dof)
+{
+       dt_kmem_free_aligned(dof, dof->dofh_loadsz);
+}
+
 static dof_hdr_t *
 dtrace_dof_property(const char *name)
 {
-       uchar_t *buf;
-       uint64_t loadsz;
-       unsigned int len, i;
+       unsigned int len;
        dof_hdr_t *dof;
 
-       /*
-        * Unfortunately, array of values in .conf files are always (and
-        * only) interpreted to be integer arrays.  We must read our DOF
-        * as an integer array, and then squeeze it into a byte array.
-        */
-       if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dtrace_devi, 0,
-           name, (int **)&buf, &len) != DDI_PROP_SUCCESS)
-               return (NULL);
+       if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed()) {
+               return NULL;
+       }
 
-       for (i = 0; i < len; i++)
-               buf[i] = (uchar_t)(((int *)buf)[i]);
+       if (!PEReadNVRAMProperty(name, NULL, &len)) {
+               return NULL;
+       }
+
+       dof = dt_kmem_alloc_aligned(len, 8, KM_SLEEP);
+
+       if (!PEReadNVRAMProperty(name, dof, &len)) {
+               dtrace_dof_destroy(dof);
+               dtrace_dof_error(NULL, "unreadable DOF");
+               return NULL;
+       }
 
        if (len < sizeof (dof_hdr_t)) {
-               ddi_prop_free(buf);
+               dtrace_dof_destroy(dof);
                dtrace_dof_error(NULL, "truncated header");
                return (NULL);
        }
 
-       if (len < (loadsz = ((dof_hdr_t *)buf)->dofh_loadsz)) {
-               ddi_prop_free(buf);
+       if (len < dof->dofh_loadsz) {
+               dtrace_dof_destroy(dof);
                dtrace_dof_error(NULL, "truncated DOF");
                return (NULL);
        }
 
-       if (loadsz >= (uint64_t)dtrace_dof_maxsize) {
-               ddi_prop_free(buf);
-               dtrace_dof_error(NULL, "oversized DOF");
+       if (len != dof->dofh_loadsz) {
+               dtrace_dof_destroy(dof);
+               dtrace_dof_error(NULL, "invalid DOF size");
                return (NULL);
        }
 
-       dof = dt_kmem_alloc_aligned(loadsz, 8, KM_SLEEP);
-       bcopy(buf, dof, loadsz);
-       ddi_prop_free(buf);
+       if (dof->dofh_loadsz >= (uint64_t)dtrace_dof_maxsize) {
+               dtrace_dof_destroy(dof);
+               dtrace_dof_error(NULL, "oversized DOF");
+               return (NULL);
+       }
 
        return (dof);
 }
 
-static void
-dtrace_dof_destroy(dof_hdr_t *dof)
-{
-       dt_kmem_free_aligned(dof, dof->dofh_loadsz);
-}
-
 /*
  * Return the dof_sec_t pointer corresponding to a given section index.  If the
  * index is not valid, dtrace_dof_error() is called and NULL is returned.  If
index 57f0f32071ea82bad86897a8127229d3fce8d6b2..d47102fe604c78e195e39917aadc47d8612f39b6 100644 (file)
@@ -586,63 +586,13 @@ ddi_report_dev(dev_info_t *devi)
 #pragma unused(devi)
 }
 
-
-static unsigned int gRegisteredProps = 0;
-static struct {
-       char name[32];          /* enough for "dof-data-" + digits */
-       int *data;
-       uint_t nelements;
-} gPropTable[16];
-
 kern_return_t _dtrace_register_anon_DOF(char *, uchar_t *, uint_t);
 
 kern_return_t
 _dtrace_register_anon_DOF(char *name, uchar_t *data, uint_t nelements)
 {
-       if (gRegisteredProps < sizeof(gPropTable)/sizeof(gPropTable[0])) {
-               int *p = (int *)_MALLOC(nelements*sizeof(int), M_TEMP, M_WAITOK);
-               
-               if (NULL == p)
-                       return KERN_FAILURE;
-                       
-               strlcpy(gPropTable[gRegisteredProps].name, name, sizeof(gPropTable[0].name));
-               gPropTable[gRegisteredProps].nelements = nelements;
-               gPropTable[gRegisteredProps].data = p;
-                       
-               while (nelements-- > 0) {
-                       *p++ = (int)(*data++);
-               }
-               
-               gRegisteredProps++;
-               return KERN_SUCCESS;
-       }
-       else
-               return KERN_FAILURE;
-}
-
-int
-ddi_prop_lookup_int_array(dev_t match_dev, dev_info_t *dip, uint_t flags,
-    const char *name, int **data, uint_t *nelements)
-{
-#pragma unused(match_dev,dip,flags)
-       unsigned int i;
-       for (i = 0; i < gRegisteredProps; ++i)
-       {
-               if (0 == strncmp(name, gPropTable[i].name,
-                                       sizeof(gPropTable[i].name))) {
-                       *data = gPropTable[i].data;
-                       *nelements = gPropTable[i].nelements;
-                       return DDI_SUCCESS;
-               }
-       }
-       return DDI_FAILURE;
-}
-       
-int
-ddi_prop_free(void *buf)
-{
-       _FREE(buf, M_TEMP);
-       return DDI_SUCCESS;
+#pragma unused(name, data, nelements)
+       return KERN_FAILURE;
 }
 
 int
index 25f052f1a4b3dd0993ce86b871cc958c4598e7c0..d90a7b15d5a391952d5959dc11fcde2a54275c2e 100644 (file)
@@ -50,6 +50,7 @@
 #include <sys/fbt.h>
 
 #include <sys/dtrace_glue.h>
+#include <san/kasan.h>
 
 /* #include <machine/trap.h> */
 struct savearea_t; /* Used anonymously */
@@ -467,6 +468,14 @@ fbt_excluded(const char* name)
                return TRUE;
        }
 
+#if KASAN
+       if (LIT_STRNSTART(name, "kasan") ||
+               LIT_STRNSTART(name, "__kasan") ||
+               LIT_STRNSTART(name, "__asan")) {
+               return TRUE;
+       }
+#endif
+
        /*
         * Place no probes that could be hit on the way to a panic.
         */
@@ -560,6 +569,13 @@ fbt_enable(void *arg, dtrace_id_t id, void *parg)
        }
 
        if (fbt->fbtp_currentval != fbt->fbtp_patchval) {
+#if KASAN
+               /* Since dtrace probes can call into KASan and vice versa, things can get
+                * very slow if we have a lot of probes. This call will disable the KASan
+                * fakestack after a threshold of probes is reached. */
+               kasan_fakestack_suspend();
+#endif
+
                (void)ml_nofault_copy( (vm_offset_t)&fbt->fbtp_patchval, (vm_offset_t)fbt->fbtp_patchpoint, 
                                                                sizeof(fbt->fbtp_patchval));
                /*
@@ -607,6 +623,10 @@ fbt_disable(void *arg, dtrace_id_t id, void *parg)
                fbt->fbtp_currentval = fbt->fbtp_savedval;
                ASSERT(ctl->mod_nenabled > 0);
                ctl->mod_nenabled--;
+
+#if KASAN
+               kasan_fakestack_resume();
+#endif
            }
        }
        dtrace_membar_consumer();
index 2923bf6446371e0b87ef9c780090c12bf3cec88e..35937cdf3c7234253af5661c15e63704485ab8da 100644 (file)
@@ -554,10 +554,10 @@ void sdt_init( void )
                                         * that symbol names the function containing the sdt probe.
                                         */
                                        for (j = 0; j < orig_st->nsyms; j++) {
-                                               uint8_t jn_type = sym[j].n_type & (N_TYPE | N_EXT);
+                                               uint8_t jn_type = sym[j].n_type & N_TYPE;
                                                char *jname = strings + sym[j].n_un.n_strx;
                                                
-                                               if (((N_SECT | N_EXT) != jn_type && (N_ABS | N_EXT) != jn_type))
+                                               if ((N_SECT != jn_type && N_ABS != jn_type))
                                                        continue;
                                                
                                                if (0 == sym[j].n_un.n_strx) /* iff a null, "", name. */
index ad71d1ffed35ed72e4113af4c7c17a453f1a778d..3fc2b9aa097c390c131d842346eeefd1f86b43b9 100644 (file)
@@ -946,6 +946,16 @@ sdt_argdesc_t sdt_args[] = {
        { "mptcp", "disconnectx", 2, 2, "sae_connid_t", "sae_connid_t" },
        { "mptcp", "disconnectx", 3, 3, "struct socket *", "sockinfo_t *" },
        { "mptcp", "disconnectx", 4, 4, "struct mptcb *", "mptsinfo_t *" },
+       {"vminfo", "kalloc", 0, 0, "vm_size_t", "vm_size_t" },
+       {"vminfo", "kalloc", 1, 1, "vm_size_t", "vm_size_t" },
+       {"vminfo", "kalloc", 2, 2, "void*", "void*" },
+       {"vminfo", "kfree", 0, 0, "vm_size_t", "vm_size_t" },
+       {"vminfo", "kfree", 1, 1, "vm_size_t", "vm_size_t" },
+       {"vminfo", "kfree", 2, 2, "void*", "void*" },
+       {"vminfo", "zalloc", 0, 0, "zone_t", "zone_t" },
+       {"vminfo", "zalloc", 1, 1, "void*", "void*" },
+       {"vminfo", "zfree", 0, 0, "zone_t", "zone_t" },
+       {"vminfo", "zfree", 1, 1, "void*", "void*" },
        { NULL, NULL, 0, 0, NULL, NULL }
 };
 
index 6553c241238a297b946bf40f3c7555438d5b9704..2ff70daee44c80274941aad1a96482873af09597 100644 (file)
@@ -56,6 +56,8 @@
 
 #include <sys/dtrace_glue.h>
 
+#include <san/kasan.h>
+
 #define DTRACE_INVOP_NOP_SKIP 1
 #define DTRACE_INVOP_MOVL_ESP_EBP 10
 #define DTRACE_INVOP_MOVL_ESP_EBP_SKIP 2
@@ -226,6 +228,18 @@ fbt_perfCallback(
                                 pDst--)
                                *pDst = pDst[-delta];
 
+#if KASAN
+                       /*
+                        * The above has moved stack objects so they are no longer in sync
+                        * with the shadow.
+                        */
+                       uintptr_t base = (uintptr_t)((uint32_t *)old_sp - delta);
+                       uintptr_t size = (uintptr_t)fp - base;
+                       if (base >= VM_MIN_KERNEL_AND_KEXT_ADDRESS) {
+                               kasan_unpoison_stack(base, size);
+                       }
+#endif
+
 /* Track the stack lift in "saved_state". */
                        saved_state = (x86_saved_state64_t *) (((uintptr_t)saved_state) + (delta << 2));
 /* Adjust the stack pointer utilized by the trampolines */
index 91ef1f2bdf7d3bdc3c2c52a9eaa5a215a4d19d0b..19a7cf3a655476c320e2f313cd3d1e7fda61410e 100644 (file)
@@ -338,13 +338,13 @@ mt_sysctl SYSCTL_HANDLER_ARGS
 
        switch ((enum mt_sysctl)arg1) {
        case MT_SUPPORTED:
-               return sysctl_io_number(req, mt_core_supported, sizeof(mt_core_supported), NULL, NULL);
+               return sysctl_io_number(req, (int)mt_core_supported, sizeof(int), NULL, NULL);
        case MT_PMIS:
                return sysctl_io_number(req, mt_pmis, sizeof(mt_pmis), NULL, NULL);
        case MT_RETROGRADE:
                return sysctl_io_number(req, mt_retrograde, sizeof(mt_retrograde), NULL, NULL);
        case MT_TASK_THREAD:
-               return sysctl_io_number(req, mt_core_supported, sizeof(mt_core_supported), NULL, NULL);
+               return sysctl_io_number(req, (int)mt_core_supported, sizeof(int), NULL, NULL);
        case MT_DEBUG: {
                int value = mt_debug;
 
index 22a932314ab27056b4c6bc2a857f45314f16c93c..36b5db056159d5c07df36052c0c277b08d4e98be 100644 (file)
@@ -293,6 +293,9 @@ void bsd_exec_setup(int);
 #if __arm64__
 __private_extern__ int bootarg_no64exec = 0;
 #endif
+#if __x86_64__
+__private_extern__ int bootarg_no32exec = 0;
+#endif
 __private_extern__ int bootarg_vnode_cache_defeat = 0;
 
 #if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
@@ -1195,6 +1198,11 @@ parse_bsd_args(void)
        if (PE_parse_boot_argn("-no64exec", namep, sizeof (namep)))
                bootarg_no64exec = 1;
 #endif
+#if __x86_64__
+       /* disable 32 bit grading */
+       if (PE_parse_boot_argn("-no32exec", namep, sizeof (namep)))
+               bootarg_no32exec = 1;
+#endif
 
        /* disable vnode_cache_is_authorized() by setting vnode_cache_defeat */
        if (PE_parse_boot_argn("-vnode_cache_defeat", namep, sizeof (namep)))
index 978b02c4997570194a335f1da043e00e2e80f6d6..5b424e71982535aa426972214b35ab2c0cff9d16 100644 (file)
@@ -1342,6 +1342,10 @@ static_assert(SIMPLE_STR_LEN % sizeof(uintptr_t) == 0);
 void
 kernel_debug_string_simple(uint32_t eventid, const char *str)
 {
+       if (!kdebug_enable) {
+               return;
+       }
+
        /* array of uintptr_ts simplifies emitting the string as arguments */
        uintptr_t str_buf[(SIMPLE_STR_LEN / sizeof(uintptr_t)) + 1] = { 0 };
        size_t len = strlcpy((char *)str_buf, str, SIMPLE_STR_LEN + 1);
@@ -3477,12 +3481,12 @@ kdbg_control(int *name, u_int namelen, user_addr_t where, size_t *sizep)
                                if (name[0] == KERN_KDWRITETR || name[0] == KERN_KDWRITETR_V3) {
                                        number = nkdbufs * sizeof(kd_buf);
 
-                                       KDBG(TRACE_WRITING_EVENTS | DBG_FUNC_START);
+                                       KDBG_RELEASE(TRACE_WRITING_EVENTS | DBG_FUNC_START);
                                        if (name[0] == KERN_KDWRITETR_V3)
                                                ret = kdbg_read(0, &number, vp, &context, RAW_VERSION3);
                                        else
                                                ret = kdbg_read(0, &number, vp, &context, RAW_VERSION1);
-                                       KDBG(TRACE_WRITING_EVENTS | DBG_FUNC_END, number);
+                                       KDBG_RELEASE(TRACE_WRITING_EVENTS | DBG_FUNC_END, number);
 
                                        *sizep = number;
                                } else {
@@ -3911,7 +3915,7 @@ kdbg_test(size_t flavor)
 }
 
 void
-kdebug_init(unsigned int n_events, char *filter_desc)
+kdebug_init(unsigned int n_events, char *filter_desc, boolean_t wrapping)
 {
        assert(filter_desc != NULL);
 
@@ -3931,7 +3935,7 @@ kdebug_init(unsigned int n_events, char *filter_desc)
                n_events = 200000;
        }
 
-       kdebug_trace_start(n_events, filter_desc, FALSE);
+       kdebug_trace_start(n_events, filter_desc, wrapping, FALSE);
 }
 
 static void
@@ -4005,10 +4009,8 @@ kdbg_set_typefilter_string(const char *filter_desc)
  */
 void
 kdebug_trace_start(unsigned int n_events, const char *filter_desc,
-                   boolean_t at_wake)
+       boolean_t wrapping, boolean_t at_wake)
 {
-       uint32_t old1, old2;
-
        if (!n_events) {
                kd_early_done = true;
                return;
@@ -4033,7 +4035,10 @@ kdebug_trace_start(unsigned int n_events, const char *filter_desc,
         * Wrapping is disabled because boot and wake tracing is interested in
         * the earliest events, at the expense of later ones.
         */
-       (void)disable_wrap(&old1, &old2);
+       if (!wrapping) {
+               uint32_t old1, old2;
+               (void)disable_wrap(&old1, &old2);
+       }
 
        if (filter_desc && filter_desc[0] != '\0') {
                if (kdbg_initialize_typefilter(NULL) == KERN_SUCCESS) {
@@ -4103,7 +4108,7 @@ kdbg_dump_trace_to_file(const char *filename)
                goto out;
        }
 
-       KDBG(TRACE_WRITING_EVENTS | DBG_FUNC_START);
+       KDBG_RELEASE(TRACE_WRITING_EVENTS | DBG_FUNC_START);
 
        kdebug_enable = 0;
        kd_ctrl_page.enabled = 0;
@@ -4153,27 +4158,6 @@ out:
        ktrace_unlock();
 }
 
-/* Helper function for filling in the BSD name for an address space
- * Defined here because the machine bindings know only Mach threads
- * and nothing about BSD processes.
- *
- * FIXME: need to grab a lock during this?
- */
-void kdbg_get_task_name(char* name_buf, int len, task_t task)
-{
-       proc_t proc;
-       
-       /* Note: we can't use thread->task (and functions that rely on it) here 
-        * because it hasn't been initialized yet when this function is called.
-        * We use the explicitly-passed task parameter instead.
-        */
-       proc = get_bsdtask_info(task);
-       if (proc != PROC_NULL)
-               snprintf(name_buf, len, "%s/%d", proc->p_comm, proc->p_pid);
-       else
-               snprintf(name_buf, len, "%p [!bsd]", task);
-}
-
 static int
 kdbg_sysctl_continuous SYSCTL_HANDLER_ARGS
 {
index 630a4c1003017e4efb0685154a6bc7b223892856..d6bf9cf91a8fa17874d7d4b76e325c2b74324c73 100644 (file)
@@ -132,7 +132,7 @@ static int  kauth_authorize_generic_callback(kauth_cred_t _credential, void *_ida
     uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
 kauth_scope_t  kauth_scope_fileop;
 
-extern int             cansignal(struct proc *, kauth_cred_t, struct proc *, int, int);
+extern int             cansignal(struct proc *, kauth_cred_t, struct proc *, int);
 extern char *  get_pathbuff(void);
 extern void            release_pathbuff(char *path);
 
@@ -484,7 +484,7 @@ kauth_authorize_process_callback(kauth_cred_t credential, __unused void *idata,
                /* arg0 - process to signal
                 * arg1 - signal to send the process
                 */
-               if (cansignal(current_proc(), credential, (struct proc *)arg0, (int)arg1, 0))
+               if (cansignal(current_proc(), credential, (struct proc *)arg0, (int)arg1))
                        return(KAUTH_RESULT_ALLOW);
                break;
        case KAUTH_PROCESS_CANTRACE:
index 0bf85095552c25cdbd8aa315c00c10293cc03f1d..92d1c43bea64332a043e658fc485a67aeddff5ae 100644 (file)
@@ -808,6 +808,93 @@ out:
        return prod_signed;
 }
 
+/*
+ * Function: csfg_get_identity
+ *
+ * Description: This function returns the codesign identity
+ *             for the fileglob
+ */
+const char *
+csfg_get_identity(struct fileglob *fg, off_t offset)
+{
+       vnode_t vp;
+       struct cs_blob *csblob = NULL;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE)
+               return NULL;
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL)
+               return NULL;
+
+       csblob = ubc_cs_blob_get(vp, -1, offset);
+       if (csblob == NULL)
+               return NULL;
+
+       return csblob_get_identity(csblob);
+}
+
+/*
+ * Function: csfg_get_platform_identifier
+ *
+ * Description: This function returns the codesign platform
+ *             identifier for the fileglob.  Assumes the fileproc
+ *             is being held busy to keep the fileglob consistent.
+ */
+uint8_t
+csfg_get_platform_identifier(struct fileglob *fg, off_t offset)
+{
+       vnode_t vp;
+
+       if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE)
+               return 0;
+
+       vp = (struct vnode *)fg->fg_data;
+       if (vp == NULL)
+               return 0;
+
+       return csvnode_get_platform_identifier(vp, offset);
+}
+
+/*
+ * Function: csvnode_get_platform_identifier
+ *
+ * Description: This function returns the codesign platform
+ *             identifier for the vnode.  Assumes a vnode reference
+ *             is held.
+ */
+uint8_t
+csvnode_get_platform_identifier(struct vnode *vp, off_t offset)
+{
+       struct cs_blob *csblob;
+       const CS_CodeDirectory *code_dir;
+
+       csblob = ubc_cs_blob_get(vp, -1, offset);
+       if (csblob == NULL)
+               return 0;
+
+       code_dir = csblob->csb_cd;
+       if (code_dir == NULL || ntohl(code_dir->length) < 8)
+               return 0;
+
+       return code_dir->platform;
+}
+
+/*
+ * Function: csproc_get_platform_identifier
+ *
+ * Description: This function returns the codesign platform
+ *             identifier for the proc.  Assumes proc will remain
+ *             valid through call.
+ */
+uint8_t
+csproc_get_platform_identifier(struct proc *p)
+{
+       if (NULL == p->p_textvp)
+               return 0;
+
+       return csvnode_get_platform_identifier(p->p_textvp, p->p_textoff);
+}
 
 uint32_t
 cs_entitlement_flags(struct proc *p)
index 06f9b82a6b06cdb7688f69355bbe73135756eb05..48904239ef98e32928cf7e512b69e072a3681f86 100644 (file)
@@ -87,6 +87,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
+#include <sys/fsctl.h>
 #include <sys/malloc.h>
 #include <sys/mman.h>
 #include <sys/syslog.h>
@@ -158,6 +159,18 @@ extern kauth_scope_t       kauth_scope_fileop;
 /* Conflict wait queue for when selects collide (opaque type) */
 extern struct waitq select_conflict_queue;
 
+#ifndef HFS_GET_BOOT_INFO
+#define HFS_GET_BOOT_INFO   (FCNTL_FS_SPECIFIC_BASE + 0x00004)
+#endif
+
+#ifndef HFS_SET_BOOT_INFO
+#define HFS_SET_BOOT_INFO   (FCNTL_FS_SPECIFIC_BASE + 0x00005)
+#endif
+
+#ifndef APFSIOC_REVERT_TO_SNAPSHOT
+#define APFSIOC_REVERT_TO_SNAPSHOT  _IOW('J', 1, u_int64_t)
+#endif
+
 #define f_flag f_fglob->fg_flag
 #define f_type f_fglob->fg_ops->fo_type
 #define f_msgcount f_fglob->fg_msgcount
@@ -2540,6 +2553,12 @@ fcntl_nocancel(proc_t p, struct fcntl_nocancel_args *uap, int32_t *retval)
 
                /* Catch any now-invalid fcntl() selectors */
                switch (uap->cmd) {
+                       case (int)APFSIOC_REVERT_TO_SNAPSHOT:
+                       case (int)FSIOC_FIOSEEKHOLE:
+                       case (int)FSIOC_FIOSEEKDATA:
+                       case HFS_GET_BOOT_INFO:
+                       case HFS_SET_BOOT_INFO:
+                       case FIOPINSWAP:
                        case F_MARKDEPENDENCY:
                                error = EINVAL;
                                goto out;
index 12885133e1b9c755ecc3674bec9e83499843d8ba..f07aa6d17ba1a1cebe1487a92991c02d8f97102d 100644 (file)
@@ -3039,51 +3039,51 @@ kqueue_dealloc(struct kqueue *kq)
        p = kq->kq_p;
        fdp = p->p_fd;
 
-       proc_fdlock(p);
-       for (i = 0; i < fdp->fd_knlistsize; i++) {
-               kn = SLIST_FIRST(&fdp->fd_knlist[i]);
-               while (kn != NULL) {
-                       if (kq == knote_get_kq(kn)) {
-                               assert((kq->kq_state & KQ_WORKLOOP) == 0);
-                               kqlock(kq);
-                               proc_fdunlock(p);
-                               /* drop it ourselves or wait */
-                               if (kqlock2knotedrop(kq, kn)) {
-                                       knote_drop(kn, p);
-                               }
-                               proc_fdlock(p);
-                               /* start over at beginning of list */
-                               kn = SLIST_FIRST(&fdp->fd_knlist[i]);
-                               continue;
-                       }
-                       kn = SLIST_NEXT(kn, kn_link);
-               }
-       }
-       knhash_lock(p);
-       proc_fdunlock(p);
-
-       if (fdp->fd_knhashmask != 0) {
-               for (i = 0; i < (int)fdp->fd_knhashmask + 1; i++) {
-                       kn = SLIST_FIRST(&fdp->fd_knhash[i]);
+       if ((kq->kq_state & KQ_WORKLOOP) == 0) {
+               proc_fdlock(p);
+               for (i = 0; i < fdp->fd_knlistsize; i++) {
+                       kn = SLIST_FIRST(&fdp->fd_knlist[i]);
                        while (kn != NULL) {
                                if (kq == knote_get_kq(kn)) {
-                                       assert((kq->kq_state & KQ_WORKLOOP) == 0);
                                        kqlock(kq);
-                                       knhash_unlock(p);
+                                       proc_fdunlock(p);
                                        /* drop it ourselves or wait */
                                        if (kqlock2knotedrop(kq, kn)) {
                                                knote_drop(kn, p);
                                        }
-                                       knhash_lock(p);
+                                       proc_fdlock(p);
                                        /* start over at beginning of list */
-                                       kn = SLIST_FIRST(&fdp->fd_knhash[i]);
+                                       kn = SLIST_FIRST(&fdp->fd_knlist[i]);
                                        continue;
                                }
                                kn = SLIST_NEXT(kn, kn_link);
                        }
                }
+               knhash_lock(p);
+               proc_fdunlock(p);
+
+               if (fdp->fd_knhashmask != 0) {
+                       for (i = 0; i < (int)fdp->fd_knhashmask + 1; i++) {
+                               kn = SLIST_FIRST(&fdp->fd_knhash[i]);
+                               while (kn != NULL) {
+                                       if (kq == knote_get_kq(kn)) {
+                                               kqlock(kq);
+                                               knhash_unlock(p);
+                                               /* drop it ourselves or wait */
+                                               if (kqlock2knotedrop(kq, kn)) {
+                                                       knote_drop(kn, p);
+                                               }
+                                               knhash_lock(p);
+                                               /* start over at beginning of list */
+                                               kn = SLIST_FIRST(&fdp->fd_knhash[i]);
+                                               continue;
+                                       }
+                                       kn = SLIST_NEXT(kn, kn_link);
+                               }
+                       }
+               }
+               knhash_unlock(p);
        }
-       knhash_unlock(p);
 
        if (kq->kq_state & KQ_WORKLOOP) {
                struct kqworkloop *kqwl = (struct kqworkloop *)kq;
@@ -4274,6 +4274,9 @@ kevent_internal(struct proc *p,
        if ((flags & (KEVENT_FLAG_DYNAMIC_KQUEUE | KEVENT_FLAG_WORKLOOP)) == KEVENT_FLAG_DYNAMIC_KQUEUE)
                return EINVAL;
 
+       if ((flags & (KEVENT_FLAG_WORKLOOP)) && (flags & (KEVENT_FLAG_WORKQ)))
+                return EINVAL;
+
        if (flags & (KEVENT_FLAG_WORKLOOP_SERVICER_ATTACH | KEVENT_FLAG_WORKLOOP_SERVICER_DETACH |
            KEVENT_FLAG_DYNAMIC_KQ_MUST_EXIST | KEVENT_FLAG_DYNAMIC_KQ_MUST_NOT_EXIST | KEVENT_FLAG_WORKLOOP_NO_WQ_THREAD)) {
 
index 90334a7903019da29ef5749e02d163746274a0f7..e5ac6b2c7c48a1f663e25852396140eeddcb5210 100644 (file)
@@ -973,6 +973,13 @@ grade:
                        exec_failure_reason = os_reason_create(OS_REASON_EXEC, EXEC_EXIT_REASON_UPX);
                        exec_failure_reason->osr_flags |= OS_REASON_FLAG_GENERATE_CRASH_REPORT;
                        exec_failure_reason->osr_flags |= OS_REASON_FLAG_CONSISTENT_FAILURE;
+               } else if (lret == LOAD_BADARCH_X86) {
+                       /* set anything that might be useful in the crash report */
+                       set_proc_name(imgp, p);
+
+                       exec_failure_reason = os_reason_create(OS_REASON_EXEC, EXEC_EXIT_REASON_NO32EXEC);
+                       exec_failure_reason->osr_flags |= OS_REASON_FLAG_GENERATE_CRASH_REPORT;
+                       exec_failure_reason->osr_flags |= OS_REASON_FLAG_CONSISTENT_FAILURE;
                } else {
                        exec_failure_reason = os_reason_create(OS_REASON_EXEC, EXEC_EXIT_REASON_BAD_MACHO);
                }
@@ -1234,12 +1241,7 @@ grade:
 #endif
 
        if (kdebug_enable) {
-               long dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4;
-
-               /*
-                * Collect the pathname for tracing
-                */
-               kdbg_trace_string(p, &dbg_arg1, &dbg_arg2, &dbg_arg3, &dbg_arg4);
+               long args[4] = {};
 
                uintptr_t fsid = 0, fileid = 0;
                if (imgp->ip_vattr) {
@@ -1251,10 +1253,15 @@ grade:
                                fsid = fileid = 0;
                        }
                }
-               KERNEL_DEBUG_CONSTANT1(TRACE_DATA_EXEC | DBG_FUNC_NONE,
-                               p->p_pid , fsid, fileid, 0, (uintptr_t)thread_tid(thread));
-               KERNEL_DEBUG_CONSTANT1(TRACE_STRING_EXEC | DBG_FUNC_NONE,
-                               dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4, (uintptr_t)thread_tid(thread));
+               KERNEL_DEBUG_CONSTANT_IST1(TRACE_DATA_EXEC, p->p_pid, fsid, fileid, 0,
+                               (uintptr_t)thread_tid(thread));
+
+               /*
+                * Collect the pathname for tracing
+                */
+               kdbg_trace_string(p, &args[0], &args[1], &args[2], &args[3]);
+               KERNEL_DEBUG_CONSTANT_IST1(TRACE_STRING_EXEC, args[0], args[1],
+                               args[2], args[3], (uintptr_t)thread_tid(thread));
        }
 
        /*
@@ -5195,13 +5202,14 @@ load_init_program(proc_t p)
  *             EIO                     An I/O error occurred
  *             EBADEXEC                The executable is corrupt/unknown
  */
-static int 
+static int
 load_return_to_errno(load_return_t lrtn)
 {
        switch (lrtn) {
        case LOAD_SUCCESS:
                return 0;
        case LOAD_BADARCH:
+       case LOAD_BADARCH_X86:
                return EBADARCH;
        case LOAD_BADMACHO:
        case LOAD_BADMACHO_UPX:
index f5ee01dc12a39fd92f0e02dac42a7e894a18350e..b2e226f0691012b2872e656b259c19d19079fdde 100644 (file)
@@ -337,6 +337,7 @@ populate_corpse_crashinfo(proc_t p, task_t corpse_task, struct rusage_superset *
                }
        }
 
+       static_assert(sizeof(struct proc_uniqidentifierinfo) == sizeof(struct crashinfo_proc_uniqidentifierinfo));
        if (KERN_SUCCESS ==
            kcdata_get_memory_addr(crash_info_ptr, TASK_CRASHINFO_BSDINFOWITHUNIQID, sizeof(struct proc_uniqidentifierinfo), &uaddr)) {
                proc_piduniqidentifierinfo(p, &p_uniqidinfo);
@@ -2181,7 +2182,7 @@ out:
  * make process 'parent' the new parent of process 'child'.
  */
 void
-proc_reparentlocked(proc_t child, proc_t parent, int cansignal, int locked)
+proc_reparentlocked(proc_t child, proc_t parent, int signallable, int locked)
 {
        proc_t oldparent = PROC_NULL;
 
@@ -2214,7 +2215,7 @@ proc_reparentlocked(proc_t child, proc_t parent, int cansignal, int locked)
 
        proc_list_unlock();
 
-       if ((cansignal != 0) && (initproc == parent) && (child->p_stat == SZOMB))
+       if ((signallable != 0) && (initproc == parent) && (child->p_stat == SZOMB))
                psignal(initproc, SIGCHLD);
        if (locked == 1)
                proc_list_lock();
index e5ae62f3fb0964c91fcb9f5e9a86d3d8cd77e5b1..6e28f3f775ecfc636da8cfdb47a51d7f90688597 100644 (file)
@@ -785,19 +785,41 @@ sysctl_zone_map_jetsam_limit SYSCTL_HANDLER_ARGS
 SYSCTL_PROC(_kern, OID_AUTO, zone_map_jetsam_limit, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
                sysctl_zone_map_jetsam_limit, "I", "Zone map jetsam limit");
 
+
+extern void get_zone_map_size(uint64_t *current_size, uint64_t *capacity);
+
+static int
+sysctl_zone_map_size_and_capacity SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+       uint64_t zstats[2];
+       get_zone_map_size(&zstats[0], &zstats[1]);
+
+       return SYSCTL_OUT(req, &zstats, sizeof(zstats));
+}
+
+SYSCTL_PROC(_kern, OID_AUTO, zone_map_size_and_capacity,
+       CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+       0, 0, &sysctl_zone_map_size_and_capacity, "Q", "Current size and capacity of the zone map");
+
+
 extern boolean_t run_zone_test(void);
 
 static int
 sysctl_run_zone_test SYSCTL_HANDLER_ARGS
 {
 #pragma unused(oidp, arg1, arg2)
-       int ret_val = run_zone_test();
+       /* require setting this sysctl to prevent sysctl -a from running this */
+       if (!req->newptr) {
+               return 0;
+       }
 
+       int ret_val = run_zone_test();
        return SYSCTL_OUT(req, &ret_val, sizeof(ret_val));
 }
 
 SYSCTL_PROC(_kern, OID_AUTO, run_zone_test,
-       CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+       CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_MASKED | CTLFLAG_LOCKED,
        0, 0, &sysctl_run_zone_test, "I", "Test zone allocator KPI");
 
 #endif /* DEBUG || DEVELOPMENT */
index 54e431d0556de2354a2ed1975806a179e0d0e7ad..a2de71f0f1a1246edb0ecef1a02a25246c1e201f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2006-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -317,7 +317,11 @@ unsigned int jetsam_aging_policy = kJetsamAgingPolicyLegacy;
 extern int corpse_for_fatal_memkill;
 extern unsigned long total_corpses_count(void) __attribute__((pure));
 extern void task_purge_all_corpses(void);
-boolean_t memorystatus_allowed_vm_map_fork(__unused task_t);
+extern uint64_t vm_purgeable_purge_task_owned(task_t task);
+boolean_t memorystatus_allowed_vm_map_fork(task_t);
+#if DEVELOPMENT || DEBUG
+void memorystatus_abort_vm_map_fork(task_t);
+#endif
 
 #if 0
 
@@ -626,7 +630,7 @@ static uint32_t memorystatus_build_state(proc_t p);
 static boolean_t memorystatus_kill_top_process(boolean_t any, boolean_t sort_flag, uint32_t cause, os_reason_t jetsam_reason, int32_t *priority, uint32_t *errors);
 static boolean_t memorystatus_kill_top_process_aggressive(uint32_t cause, int aggr_count, int32_t priority_max, uint32_t *errors);
 static boolean_t memorystatus_kill_elevated_process(uint32_t cause, os_reason_t jetsam_reason, int aggr_count, uint32_t *errors);
-static boolean_t memorystatus_kill_hiwat_proc(uint32_t *errors);
+static boolean_t memorystatus_kill_hiwat_proc(uint32_t *errors, boolean_t *purged);
 
 static boolean_t memorystatus_kill_process_async(pid_t victim_pid, uint32_t cause);
 
@@ -3379,14 +3383,18 @@ memorystatus_action_needed(void)
 static boolean_t
 memorystatus_act_on_hiwat_processes(uint32_t *errors, uint32_t *hwm_kill, boolean_t *post_snapshot, __unused boolean_t *is_critical)
 {
-       boolean_t killed = memorystatus_kill_hiwat_proc(errors);
+       boolean_t purged = FALSE;
+       boolean_t killed = memorystatus_kill_hiwat_proc(errors, &purged);
 
        if (killed) {
                *hwm_kill = *hwm_kill + 1;
                *post_snapshot = TRUE;
                return TRUE;
        } else {
-               memorystatus_hwm_candidates = FALSE;
+               if (purged == FALSE) {
+                       /* couldn't purge and couldn't kill */
+                       memorystatus_hwm_candidates = FALSE;
+               }
        }
 
 #if CONFIG_JETSAM
@@ -4123,6 +4131,10 @@ memorystatus_get_task_memory_region_count(task_t task, uint64_t *count)
        *count = get_task_memory_region_count(task);
 }
 
+
+#define MEMORYSTATUS_VM_MAP_FORK_ALLOWED     0x100000000
+#define MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED 0x200000000
+
 #if DEVELOPMENT || DEBUG
 
 /*
@@ -4130,11 +4142,15 @@ memorystatus_get_task_memory_region_count(task_t task, uint64_t *count)
  *   set a new pidwatch value
  *     or
  *   get the current pidwatch value
+ *
+ * The pidwatch_val starts out with a PID to watch for in the map_fork path.
+ * Its value is:
+ * - OR'd with MEMORYSTATUS_VM_MAP_FORK_ALLOWED if we allow the map_fork.
+ * - OR'd with MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED if we disallow the map_fork.
+ * - set to -1ull if the map_fork() is aborted for other reasons.
  */
 
 uint64_t memorystatus_vm_map_fork_pidwatch_val = 0;
-#define MEMORYSTATUS_VM_MAP_FORK_ALLOWED     0x100000000
-#define MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED 0x200000000
 
 static int sysctl_memorystatus_vm_map_fork_pidwatch SYSCTL_HANDLER_ARGS {
 #pragma unused(oidp, arg1, arg2)
@@ -4172,30 +4188,40 @@ SYSCTL_PROC(_kern, OID_AUTO, memorystatus_vm_map_fork_pidwatch, CTLTYPE_QUAD | C
             0, 0, sysctl_memorystatus_vm_map_fork_pidwatch, "Q", "get/set pid watched for in vm_map_fork");
 
 
-#define SET_VM_MAP_FORK_PIDWATCH_ALLOWED(task)                                                 \
-MACRO_BEGIN                                                                                    \
-if (memorystatus_vm_map_fork_pidwatch_val != 0) {                                              \
-       proc_t p = get_bsdtask_info(task);                                                      \
-       if (p && (memorystatus_vm_map_fork_pidwatch_val == (uint64_t)p->p_pid)) {               \
-               memorystatus_vm_map_fork_pidwatch_val |= MEMORYSTATUS_VM_MAP_FORK_ALLOWED;      \
-       }                                                                                       \
-}                                                                                              \
-MACRO_END
+/*
+ * Record if a watched process fails to qualify for a vm_map_fork().
+ */
+void
+memorystatus_abort_vm_map_fork(task_t task)
+{
+       if (memorystatus_vm_map_fork_pidwatch_val != 0) {
+               proc_t p = get_bsdtask_info(task);
+               if (p != NULL && memorystatus_vm_map_fork_pidwatch_val == (uint64_t)p->p_pid) {
+                       memorystatus_vm_map_fork_pidwatch_val = -1ull;
+               }
+       }
+}
 
-#define SET_VM_MAP_FORK_PIDWATCH_NOT_ALLOWED(task)                                             \
-MACRO_BEGIN                                                                                    \
-if (memorystatus_vm_map_fork_pidwatch_val != 0) {                                              \
-       proc_t p = get_bsdtask_info(task);                                                      \
-       if (p && (memorystatus_vm_map_fork_pidwatch_val == (uint64_t)p->p_pid)) {               \
-               memorystatus_vm_map_fork_pidwatch_val |= MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED;  \
-       }                                                                                       \
-}                                                                                              \
-MACRO_END
+static void
+set_vm_map_fork_pidwatch(task_t task, uint64_t x)
+{
+       if (memorystatus_vm_map_fork_pidwatch_val != 0) {
+               proc_t p = get_bsdtask_info(task);
+               if (p && (memorystatus_vm_map_fork_pidwatch_val == (uint64_t)p->p_pid)) {
+                       memorystatus_vm_map_fork_pidwatch_val |= x;
+               }
+       }
+}
 
 #else /* DEVELOPMENT || DEBUG */
 
-#define SET_VM_MAP_FORK_PIDWATCH_ALLOWED(task)
-#define SET_VM_MAP_FORK_PIDWATCH_NOT_ALLOWED(task)
+
+static void
+set_vm_map_fork_pidwatch(task_t task, uint64_t x)
+{
+#pragma unused(task)
+#pragma unused(x)
+}
 
 #endif /* DEVELOPMENT || DEBUG */
 
@@ -4221,18 +4247,18 @@ MACRO_END
  *     munch memory up to the system-wide task limit.
  */
 boolean_t
-memorystatus_allowed_vm_map_fork(__unused task_t task)
+memorystatus_allowed_vm_map_fork(task_t task)
 {
        boolean_t is_allowed = TRUE;   /* default */
 
 #if CONFIG_EMBEDDED
 
-       uint64_t footprint_in_bytes = 0;
-       uint64_t purgeable_in_bytes = 0;
-       uint64_t max_allowed_bytes = 0;
+       uint64_t footprint_in_bytes;
+       uint64_t purgeable_in_bytes;
+       uint64_t max_allowed_bytes;
 
        if (max_task_footprint_mb == 0) {
-               SET_VM_MAP_FORK_PIDWATCH_ALLOWED(task);
+               set_vm_map_fork_pidwatch(task, MEMORYSTATUS_VM_MAP_FORK_ALLOWED);
                return (is_allowed);
        }
 
@@ -4242,28 +4268,22 @@ memorystatus_allowed_vm_map_fork(__unused task_t task)
        /*
         * Maximum is half the system-wide task limit.
         */
-       max_allowed_bytes = ((((uint64_t)max_task_footprint_mb) * 1024ULL * 1024ULL) >> 1);
+       max_allowed_bytes = ((uint64_t)max_task_footprint_mb * 1024 * 1024) >> 1;
 
        if (footprint_in_bytes > purgeable_in_bytes) {
                footprint_in_bytes -= purgeable_in_bytes;
        }
 
-       if (footprint_in_bytes <= max_allowed_bytes) {
-               SET_VM_MAP_FORK_PIDWATCH_ALLOWED(task);
-               return (is_allowed);
-       } else {
+       if (footprint_in_bytes > max_allowed_bytes) {
                printf("memorystatus disallowed vm_map_fork %lld  %lld\n", footprint_in_bytes, max_allowed_bytes);
-               SET_VM_MAP_FORK_PIDWATCH_NOT_ALLOWED(task);
+               set_vm_map_fork_pidwatch(task, MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED);
                return (!is_allowed);
        }
+#endif /* CONFIG_EMBEDDED */
 
-#else /* CONFIG_EMBEDDED */
-
-       SET_VM_MAP_FORK_PIDWATCH_ALLOWED(task);
+       set_vm_map_fork_pidwatch(task, MEMORYSTATUS_VM_MAP_FORK_ALLOWED);
        return (is_allowed);
 
-#endif /* CONFIG_EMBEDDED */
-
 }
 
 static void
@@ -4631,7 +4651,7 @@ memorystatus_init_snapshot_vmstats(memorystatus_jetsam_snapshot_t *snapshot)
        mach_msg_type_number_t  count = HOST_VM_INFO64_COUNT;
        vm_statistics64_data_t  vm_stat;
 
-       if ((kr = host_statistics64(host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stat, &count) != KERN_SUCCESS)) {
+       if ((kr = host_statistics64(host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stat, &count)) != KERN_SUCCESS) {
                printf("memorystatus_init_jetsam_snapshot_stats: host_statistics64 failed with %d\n", kr);
                memset(&snapshot->stats, 0, sizeof(snapshot->stats));
        } else {
@@ -4784,6 +4804,137 @@ memorystatus_cmd_test_jetsam_sort(int priority, int sort_order) {
 
 #endif /* DEVELOPMENT || DEBUG */
 
+/*
+ * Prepare the process to be killed (set state, update snapshot) and kill it.
+ */
+static uint64_t memorystatus_purge_before_jetsam_success = 0;
+
+static boolean_t
+memorystatus_kill_proc(proc_t p, uint32_t cause, os_reason_t jetsam_reason, boolean_t *killed)
+{
+       pid_t aPid = 0;
+       uint32_t aPid_ep = 0;
+
+       uint64_t killtime = 0;
+        clock_sec_t     tv_sec;
+        clock_usec_t    tv_usec;
+        uint32_t        tv_msec;
+       boolean_t       retval = FALSE;
+       uint64_t        num_pages_purged = 0;
+
+       aPid = p->p_pid;
+       aPid_ep = p->p_memstat_effectivepriority;
+
+       if (cause != kMemorystatusKilledVnodes && cause != kMemorystatusKilledZoneMapExhaustion) {
+               /*
+                * Genuine memory pressure and not other (vnode/zone) resource exhaustion.
+                */
+               boolean_t success = FALSE;
+
+               networking_memstatus_callout(p, cause);
+               num_pages_purged = vm_purgeable_purge_task_owned(p->task);
+
+               if (num_pages_purged) {
+                       /*
+                        * We actually purged something and so let's
+                        * check if we need to continue with the kill.
+                        */
+                       if (cause == kMemorystatusKilledHiwat) {
+                               uint64_t footprint_in_bytes = get_task_phys_footprint(p->task);
+                               uint64_t memlimit_in_bytes  = (((uint64_t)p->p_memstat_memlimit) * 1024ULL * 1024ULL);  /* convert MB to bytes */
+                               success = (footprint_in_bytes <= memlimit_in_bytes);
+                       } else {
+                               success = (memorystatus_avail_pages_below_pressure() == FALSE);
+                       }
+
+                       if (success) {
+
+                               memorystatus_purge_before_jetsam_success++;
+
+                               os_log_with_startup_serial(OS_LOG_DEFAULT, "memorystatus: purged %llu pages from pid %d [%s] and avoided %s\n",
+                               num_pages_purged, aPid, (*p->p_name ? p->p_name : "unknown"),  memorystatus_kill_cause_name[cause]);
+
+                               *killed = FALSE;
+
+                               return TRUE;
+                       }
+               }
+       }
+
+#if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
+       MEMORYSTATUS_DEBUG(1, "jetsam: %s pid %d [%s] - %lld Mb > 1 (%d Mb)\n",
+                          (memorystatus_jetsam_policy & kPolicyDiagnoseActive) ? "suspending": "killing",
+                          aPid, (*p->p_name ? p->p_name : "unknown"),
+                          (footprint_in_bytes / (1024ULL * 1024ULL)),  /* converted bytes to MB */
+                          p->p_memstat_memlimit);
+#endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
+
+       killtime = mach_absolute_time();
+       absolutetime_to_microtime(killtime, &tv_sec, &tv_usec);
+       tv_msec = tv_usec / 1000;
+
+#if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
+       if (memorystatus_jetsam_policy & kPolicyDiagnoseActive) {
+               if (cause == kMemorystatusKilledHiwat) {
+                       MEMORYSTATUS_DEBUG(1, "jetsam: suspending pid %d [%s] for diagnosis - memorystatus_available_pages: %d\n",
+                               aPid, (*p->p_name ? p->p_name: "(unknown)"), memorystatus_available_pages);
+               } else {
+                       int activeProcess = p->p_memstat_state & P_MEMSTAT_FOREGROUND;
+                       if (activeProcess) {
+                               MEMORYSTATUS_DEBUG(1, "jetsam: suspending pid %d [%s] (active) for diagnosis - memorystatus_available_pages: %d\n",
+                                       aPid, (*p->p_name ? p->p_name: "(unknown)"), memorystatus_available_pages);
+
+                                       if (memorystatus_jetsam_policy & kPolicyDiagnoseFirst) {
+                                               jetsam_diagnostic_suspended_one_active_proc = 1;
+                                               printf("jetsam: returning after suspending first active proc - %d\n", aPid);
+                                       }
+                       }
+               }
+
+               memorystatus_update_jetsam_snapshot_entry_locked(p, kMemorystatusKilledDiagnostic, killtime);
+               p->p_memstat_state |= P_MEMSTAT_DIAG_SUSPENDED;
+
+               if (p) {
+                       task_suspend(p->task);
+                       *killed = TRUE;
+               }
+       } else
+#endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
+       {
+               memorystatus_update_jetsam_snapshot_entry_locked(p, cause, killtime);
+
+               char kill_reason_string[128];
+
+               if (cause == kMemorystatusKilledHiwat) {
+                       strlcpy(kill_reason_string, "killing_highwater_process", 128);
+               } else {
+                       if (aPid_ep == JETSAM_PRIORITY_IDLE) {
+                               strlcpy(kill_reason_string, "killing_idle_process", 128);
+                       } else {
+                               strlcpy(kill_reason_string, "killing_top_process", 128);
+                       }
+               }
+
+               os_log_with_startup_serial(OS_LOG_DEFAULT, "%lu.%03d memorystatus: %s pid %d [%s] (%s %d) - memorystatus_available_pages: %llu\n",
+                      (unsigned long)tv_sec, tv_msec, kill_reason_string,
+                      aPid, (*p->p_name ? p->p_name : "unknown"),
+                      memorystatus_kill_cause_name[cause], aPid_ep, (uint64_t)memorystatus_available_pages);
+
+               /*
+                * memorystatus_do_kill drops a reference, so take another one so we can
+                * continue to use this exit reason even after memorystatus_do_kill()
+                * returns
+                */
+               os_reason_ref(jetsam_reason);
+
+               retval = memorystatus_do_kill(p, cause, jetsam_reason);
+
+               *killed = retval;
+       }
+
+       return retval;
+}
+
 /*
  * Jetsam the first process in the queue.
  */
@@ -4793,14 +4944,9 @@ memorystatus_kill_top_process(boolean_t any, boolean_t sort_flag, uint32_t cause
 {
        pid_t aPid;
        proc_t p = PROC_NULL, next_p = PROC_NULL;
-       boolean_t new_snapshot = FALSE, force_new_snapshot = FALSE, killed = FALSE;
-       int kill_count = 0;
+       boolean_t new_snapshot = FALSE, force_new_snapshot = FALSE, killed = FALSE, freed_mem = FALSE;
        unsigned int i = 0;
        uint32_t aPid_ep;
-       uint64_t killtime = 0;
-        clock_sec_t     tv_sec;
-        clock_usec_t    tv_usec;
-        uint32_t        tv_msec;
        int32_t         local_max_kill_prio = JETSAM_PRIORITY_IDLE;
 
 #ifndef CONFIG_FREEZE
@@ -4859,7 +5005,6 @@ memorystatus_kill_top_process(boolean_t any, boolean_t sort_flag, uint32_t cause
        next_p = memorystatus_get_first_proc_locked(&i, TRUE);
        while (next_p && (next_p->p_memstat_effectivepriority <= local_max_kill_prio)) {
 #if DEVELOPMENT || DEBUG
-               int activeProcess;
                int procSuspendedForDiagnosis;
 #endif /* DEVELOPMENT || DEBUG */
         
@@ -4867,7 +5012,6 @@ memorystatus_kill_top_process(boolean_t any, boolean_t sort_flag, uint32_t cause
                next_p = memorystatus_get_next_proc_locked(&i, p, TRUE);
                
 #if DEVELOPMENT || DEBUG
-               activeProcess = p->p_memstat_state & P_MEMSTAT_FOREGROUND;
                procSuspendedForDiagnosis = p->p_memstat_state & P_MEMSTAT_DIAG_SUSPENDED;
 #endif /* DEVELOPMENT || DEBUG */
                
@@ -4915,6 +5059,28 @@ memorystatus_kill_top_process(boolean_t any, boolean_t sort_flag, uint32_t cause
                } else
 #endif
                {
+                       if (proc_ref_locked(p) == p) {
+                               /*
+                                * Mark as terminated so that if exit1() indicates success, but the process (for example)
+                                * is blocked in task_exception_notify(), it'll be skipped if encountered again - see
+                                * <rdar://problem/13553476>. This is cheaper than examining P_LEXIT, which requires the
+                                * acquisition of the proc lock.
+                                */
+                               p->p_memstat_state |= P_MEMSTAT_TERMINATED;
+
+                               proc_list_unlock();
+                       } else {
+                               /*
+                                * We need to restart the search again because
+                                * proc_ref_locked _can_ drop the proc_list lock
+                                * and we could have lost our stored next_p via
+                                * an exit() on another core.
+                                */
+                               i = 0;
+                               next_p = memorystatus_get_first_proc_locked(&i, TRUE);
+                               continue;
+                       }
+
                        /*
                         * Capture a snapshot if none exists and:
                         * - we are forcing a new snapshot creation, either because:
@@ -4928,101 +5094,36 @@ memorystatus_kill_top_process(boolean_t any, boolean_t sort_flag, uint32_t cause
                                memorystatus_init_jetsam_snapshot_locked(NULL,0);
                                new_snapshot = TRUE;
                        }
-                       
-                       /* 
-                        * Mark as terminated so that if exit1() indicates success, but the process (for example)
-                        * is blocked in task_exception_notify(), it'll be skipped if encountered again - see 
-                        * <rdar://problem/13553476>. This is cheaper than examining P_LEXIT, which requires the 
-                        * acquisition of the proc lock.
-                        */
-                       p->p_memstat_state |= P_MEMSTAT_TERMINATED;
 
-                       killtime = mach_absolute_time();
-                       absolutetime_to_microtime(killtime, &tv_sec, &tv_usec);
-                       tv_msec = tv_usec / 1000;
-                       
-#if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
-                       if ((memorystatus_jetsam_policy & kPolicyDiagnoseActive) && activeProcess) {
-                               MEMORYSTATUS_DEBUG(1, "jetsam: suspending pid %d [%s] (active) for diagnosis - memory_status_level: %d\n",
-                                       aPid, (*p->p_name ? p->p_name: "(unknown)"), memorystatus_level);
-                               memorystatus_update_jetsam_snapshot_entry_locked(p, kMemorystatusKilledDiagnostic, killtime);
-                               p->p_memstat_state |= P_MEMSTAT_DIAG_SUSPENDED;
-                               if (memorystatus_jetsam_policy & kPolicyDiagnoseFirst) {
-                                       jetsam_diagnostic_suspended_one_active_proc = 1;
-                                       printf("jetsam: returning after suspending first active proc - %d\n", aPid);
-                               }
-                               
-                               p = proc_ref_locked(p);
-                               proc_list_unlock();
-                               if (p) {
-                                       task_suspend(p->task);
+                       freed_mem = memorystatus_kill_proc(p, cause, jetsam_reason, &killed); /* purged and/or killed 'p' */
+                       /* Success? */
+                       if (freed_mem) {
+                               if (killed) {
                                        if (priority) {
                                                *priority = aPid_ep;
                                        }
-                                       proc_rele(p);
-                                       killed = TRUE;
-                               }
-                               
-                               goto exit;
-                       } else
-#endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
-                       {
-                               /* Shift queue, update stats */
-                               memorystatus_update_jetsam_snapshot_entry_locked(p, cause, killtime);
-
-                               if (proc_ref_locked(p) == p) {
-                                       proc_list_unlock();
-                                       os_log_with_startup_serial(OS_LOG_DEFAULT, "%lu.%03d memorystatus: %s pid %d [%s] (%s %d) - memorystatus_available_pages: %llu\n",
-                                              (unsigned long)tv_sec, tv_msec,
-                                              ((aPid_ep == JETSAM_PRIORITY_IDLE) ? "killing_idle_process" : "killing_top_process"),
-                                              aPid, (*p->p_name ? p->p_name : "unknown"),
-                                              memorystatus_kill_cause_name[cause], aPid_ep, (uint64_t)memorystatus_available_pages);
-
-                                       /*
-                                        * memorystatus_do_kill() drops a reference, so take another one so we can
-                                        * continue to use this exit reason even after memorystatus_do_kill()
-                                        * returns.
-                                        */
-                                       os_reason_ref(jetsam_reason);
-
-                                       killed = memorystatus_do_kill(p, cause, jetsam_reason);
-
-                                       /* Success? */
-                                       if (killed) {
-                                               if (priority) {
-                                                       *priority = aPid_ep;
-                                               }
-                                               proc_rele(p);
-                                               kill_count++;
-                                               goto exit;
-                                       }
-                               
-                                       /*
-                                        * Failure - first unwind the state,
-                                        * then fall through to restart the search.
-                                        */
+                               } else {
+                                       /* purged */
                                        proc_list_lock();
-                                       proc_rele_locked(p);
                                        p->p_memstat_state &= ~P_MEMSTAT_TERMINATED;
-                                       p->p_memstat_state |= P_MEMSTAT_ERROR;
-                                       *errors += 1;
+                                       proc_list_unlock();
                                }
-                               
-                               /*
-                                * Failure - restart the search.
-                                *
-                                * We might have raced with "p" exiting on another core, resulting in no
-                                * ref on "p".  Or, we may have failed to kill "p".
-                                *
-                                * Either way, we fall thru to here, leaving the proc in the
-                                * P_MEMSTAT_TERMINATED state.
-                                *
-                                * And, we hold the the proc_list_lock at this point.
-                                */
-
-                               i = 0;
-                               next_p = memorystatus_get_first_proc_locked(&i, TRUE);
+                               proc_rele(p);
+                               goto exit;
                        }
+               
+                       /*
+                        * Failure - first unwind the state,
+                        * then fall through to restart the search.
+                        */
+                       proc_list_lock();
+                       proc_rele_locked(p);
+                       p->p_memstat_state &= ~P_MEMSTAT_TERMINATED;
+                       p->p_memstat_state |= P_MEMSTAT_ERROR;
+                       *errors += 1;
+
+                       i = 0;
+                       next_p = memorystatus_get_first_proc_locked(&i, TRUE);
                }
        }
        
@@ -5039,7 +5140,7 @@ exit:
        }
        
        KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_MEMSTAT, BSD_MEMSTAT_JETSAM) | DBG_FUNC_END,
-                             memorystatus_available_pages, killed ? aPid : 0, kill_count, 0, 0);
+                             memorystatus_available_pages, killed ? aPid : 0, 0, 0, 0);
 
        return killed;
 }
@@ -5283,18 +5384,13 @@ exit:
 }
 
 static boolean_t
-memorystatus_kill_hiwat_proc(uint32_t *errors)
+memorystatus_kill_hiwat_proc(uint32_t *errors, boolean_t *purged)
 {
        pid_t aPid = 0;
        proc_t p = PROC_NULL, next_p = PROC_NULL;
-       boolean_t new_snapshot = FALSE, killed = FALSE;
-       int kill_count = 0;
+       boolean_t new_snapshot = FALSE, killed = FALSE, freed_mem = FALSE;
        unsigned int i = 0;
        uint32_t aPid_ep;
-       uint64_t killtime = 0;
-        clock_sec_t     tv_sec;
-        clock_usec_t    tv_usec;
-        uint32_t        tv_msec;
        os_reason_t jetsam_reason = OS_REASON_NULL;
        KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_MEMSTAT, BSD_MEMSTAT_JETSAM_HIWAT) | DBG_FUNC_START,
                memorystatus_available_pages, 0, 0, 0, 0);
@@ -5352,93 +5448,61 @@ memorystatus_kill_hiwat_proc(uint32_t *errors)
                if (skip) {
                        continue;
                } else {
-#if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
-                       MEMORYSTATUS_DEBUG(1, "jetsam: %s pid %d [%s] - %lld Mb > 1 (%d Mb)\n",
-                                          (memorystatus_jetsam_policy & kPolicyDiagnoseActive) ? "suspending": "killing",
-                                          aPid, (*p->p_name ? p->p_name : "unknown"),
-                                          (footprint_in_bytes / (1024ULL * 1024ULL)),  /* converted bytes to MB */
-                                          p->p_memstat_memlimit);
-#endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
-                               
+
                        if (memorystatus_jetsam_snapshot_count == 0) {
                                memorystatus_init_jetsam_snapshot_locked(NULL,0);
-                               new_snapshot = TRUE;
-                       }
-                       
-                       p->p_memstat_state |= P_MEMSTAT_TERMINATED;
+                               new_snapshot = TRUE;
+                       }
+       
+                       if (proc_ref_locked(p) == p) {
+                               /*
+                                * Mark as terminated so that if exit1() indicates success, but the process (for example)
+                                * is blocked in task_exception_notify(), it'll be skipped if encountered again - see
+                                * <rdar://problem/13553476>. This is cheaper than examining P_LEXIT, which requires the
+                                * acquisition of the proc lock.
+                                */
+                               p->p_memstat_state |= P_MEMSTAT_TERMINATED;
 
-                       killtime = mach_absolute_time();
-                       absolutetime_to_microtime(killtime, &tv_sec, &tv_usec);
-                       tv_msec = tv_usec / 1000;
-                               
-#if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
-                       if (memorystatus_jetsam_policy & kPolicyDiagnoseActive) {
-                               MEMORYSTATUS_DEBUG(1, "jetsam: pid %d suspended for diagnosis - memorystatus_available_pages: %d\n", aPid, memorystatus_available_pages);
-                               memorystatus_update_jetsam_snapshot_entry_locked(p, kMemorystatusKilledDiagnostic, killtime);
-                               p->p_memstat_state |= P_MEMSTAT_DIAG_SUSPENDED;
-                               
-                               p = proc_ref_locked(p);
                                proc_list_unlock();
-                               if (p) {
-                                       task_suspend(p->task);
-                                       proc_rele(p);
-                                       killed = TRUE;
-                               }
-                               
-                               goto exit;
-                       } else
-#endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
-                       {
-                               memorystatus_update_jetsam_snapshot_entry_locked(p, kMemorystatusKilledHiwat, killtime);
-                               
-                               if (proc_ref_locked(p) == p) {
-                                       proc_list_unlock();
-
-                                       os_log_with_startup_serial(OS_LOG_DEFAULT, "%lu.%03d memorystatus: killing_highwater_process pid %d [%s] (highwater %d) - memorystatus_available_pages: %llu\n",
-                                              (unsigned long)tv_sec, tv_msec, aPid, (*p->p_name ? p->p_name : "unknown"), aPid_ep, (uint64_t)memorystatus_available_pages);
-
-                                       /*
-                                        * memorystatus_do_kill drops a reference, so take another one so we can
-                                        * continue to use this exit reason even after memorystatus_do_kill()
-                                        * returns
-                                        */
-                                       os_reason_ref(jetsam_reason);
-
-                                       killed = memorystatus_do_kill(p, kMemorystatusKilledHiwat, jetsam_reason);
+                       } else {
+                               /*
+                                * We need to restart the search again because
+                                * proc_ref_locked _can_ drop the proc_list lock
+                                * and we could have lost our stored next_p via
+                                * an exit() on another core.
+                                */
+                               i = 0;
+                               next_p = memorystatus_get_first_proc_locked(&i, TRUE);
+                               continue;
+                       }
+               
+                       freed_mem = memorystatus_kill_proc(p, kMemorystatusKilledHiwat, jetsam_reason, &killed); /* purged and/or killed 'p' */
 
-                                       /* Success? */
-                                       if (killed) {
-                                               proc_rele(p);
-                                               kill_count++;
-                                               goto exit;
-                                       }
+                       /* Success? */
+                       if (freed_mem) {
+                               if (killed == FALSE) {
+                                       /* purged 'p'..don't reset HWM candidate count */
+                                       *purged = TRUE;
 
-                                       /*
-                                        * Failure - first unwind the state,
-                                        * then fall through to restart the search.
-                                        */
                                        proc_list_lock();
-                                       proc_rele_locked(p);
                                        p->p_memstat_state &= ~P_MEMSTAT_TERMINATED;
-                                       p->p_memstat_state |= P_MEMSTAT_ERROR;
-                                       *errors += 1;
+                                       proc_list_unlock();
                                }
-
-                               /*
-                                * Failure - restart the search.
-                                *
-                                * We might have raced with "p" exiting on another core, resulting in no
-                                * ref on "p".  Or, we may have failed to kill "p".
-                                *
-                                * Either way, we fall thru to here, leaving the proc in the 
-                                * P_MEMSTAT_TERMINATED state.
-                                *
-                                * And, we hold the the proc_list_lock at this point.
-                                */
-
-                               i = 0;
-                               next_p = memorystatus_get_first_proc_locked(&i, TRUE);
+                               proc_rele(p);
+                               goto exit;
                        }
+                       /*
+                        * Failure - first unwind the state,
+                        * then fall through to restart the search.
+                        */
+                       proc_list_lock();
+                       proc_rele_locked(p);
+                       p->p_memstat_state &= ~P_MEMSTAT_TERMINATED;
+                       p->p_memstat_state |= P_MEMSTAT_ERROR;
+                       *errors += 1;
+
+                       i = 0;
+                       next_p = memorystatus_get_first_proc_locked(&i, TRUE);
                }
        }
        
@@ -5455,7 +5519,7 @@ exit:
        }
        
        KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_MEMSTAT, BSD_MEMSTAT_JETSAM_HIWAT) | DBG_FUNC_END, 
-                             memorystatus_available_pages, killed ? aPid : 0, kill_count, 0, 0);
+                             memorystatus_available_pages, killed ? aPid : 0, 0, 0, 0);
 
        return killed;
 }
@@ -7253,7 +7317,7 @@ memorystatus_get_priority_list(memorystatus_priority_entry_t **list_ptr, size_t
        }
 
        *list_ptr = (memorystatus_priority_entry_t*)kalloc(*list_size);
-       if (!list_ptr) {
+       if (!*list_ptr) {
                return ENOMEM;
        }
 
index d3a9e2c060fb397e25cfdc225fc3fa8f47f357a8..35115e557ec8afca31263684985875b3d4c473f8 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*-
@@ -154,6 +154,9 @@ SYSCTL_NODE(, CTL_MACHDEP, machdep, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 SYSCTL_NODE(, CTL_USER,          user,   CTLFLAG_RW|CTLFLAG_LOCKED, 0,
        "user-level");
 
+SYSCTL_NODE(_kern, OID_AUTO, bridge, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
+       "bridge");
+
 #define SYSCTL_RETURN(r, x)    SYSCTL_OUT(r, &x, sizeof(x))
 
 /******************************************************************************
@@ -171,7 +174,7 @@ SYSCTL_NODE(, CTL_USER,       user,   CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 
 
 /*
- * Supporting some variables requires us to do "real" work.  We 
+ * Supporting some variables requires us to do "real" work.  We
  * gather some of that here.
  */
 static int
@@ -405,7 +408,7 @@ SYSCTL_INT     (_hw, OID_AUTO, packages, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOC
  *
  * If the feature is not present, the node should either not be registered,
  * or it should return -1.  If the feature is present, the node should return
- * 0.  If the feature is present and its use is advised, the node should 
+ * 0.  If the feature is present and its use is advised, the node should
  * return 1.
  */
 SYSCTL_NODE(_hw, OID_AUTO, optional, CTLFLAG_RW|CTLFLAG_LOCKED, NULL, "optional features");
@@ -457,7 +460,7 @@ sysctl_cpu_capability
 {
        uint64_t        mask = (uint64_t) (uintptr_t) arg1;
        boolean_t       is_capable = (_get_cpu_capabilities() & mask) != 0;
+
        return SYSCTL_OUT(req, &is_capable, sizeof(is_capable));
 
 }
index 1c6979473b11b2027b02b29070b0e22672c67f1a..f373a0c7918b0273cd2c3f6e0271387439c1c02a 100644 (file)
@@ -301,7 +301,8 @@ mmap(proc_t p, struct mmap_args *uap, user_addr_t *retval)
                         */
                        alloc_flags = fd & (VM_FLAGS_ALIAS_MASK |
                                            VM_FLAGS_SUPERPAGE_MASK |
-                                           VM_FLAGS_PURGABLE);
+                                           VM_FLAGS_PURGABLE |
+                                           VM_FLAGS_4GB_CHUNK);
                        if (alloc_flags != fd) {
                                /* reject if there are any extra flags */
                                return EINVAL;
@@ -607,6 +608,14 @@ map_file_retry:
                        /* strictly limit access to "prot" */
                        maxprot &= prot;
                }
+
+               vm_object_offset_t end_pos = 0;
+               if (os_add_overflow(user_size, file_pos, &end_pos)) {
+                       vnode_put(vp);
+                       error = EINVAL;
+                       goto bad;
+               }
+
                result = vm_map_enter_mem_object_control(user_map,
                                                 &user_addr, user_size,
                                                 0, alloc_flags, vmk_flags,
@@ -1012,14 +1021,14 @@ mincore(__unused proc_t p, struct mincore_args *uap, __unused int32_t *retval)
        vm_map_t map = VM_MAP_NULL;
        user_addr_t vec = 0;
        int error = 0;
-       int vecindex = 0, lastvecindex = 0;
+       int lastvecindex = 0;
        int mincoreinfo=0;
        int pqueryinfo = 0;
        unsigned int pqueryinfo_vec_size = 0;
        vm_page_info_basic_t info = NULL;
        mach_msg_type_number_t count = 0;
        char *kernel_vec = NULL;
-       int req_vec_size_pages = 0, cur_vec_size_pages = 0;
+       unsigned int req_vec_size_pages = 0, cur_vec_size_pages = 0, vecindex = 0;
        kern_return_t kr = KERN_SUCCESS;
 
        map = current_map();
@@ -1045,7 +1054,7 @@ mincore(__unused proc_t p, struct mincore_args *uap, __unused int32_t *retval)
         */
 
        req_vec_size_pages = (end - addr) >> PAGE_SHIFT;
-       cur_vec_size_pages = MIN(req_vec_size_pages, (int)(MAX_PAGE_RANGE_QUERY >> PAGE_SHIFT));
+       cur_vec_size_pages = MIN(req_vec_size_pages, (MAX_PAGE_RANGE_QUERY >> PAGE_SHIFT));
 
        kernel_vec = (void*) _MALLOC(cur_vec_size_pages * sizeof(char), M_TEMP, M_WAITOK | M_ZERO);
 
@@ -1129,7 +1138,7 @@ mincore(__unused proc_t p, struct mincore_args *uap, __unused int32_t *retval)
                 */
                vec += cur_vec_size_pages * sizeof(char);
                req_vec_size_pages = (end - addr) >> PAGE_SHIFT;
-               cur_vec_size_pages = MIN(req_vec_size_pages, (int)(MAX_PAGE_RANGE_QUERY >> PAGE_SHIFT));
+               cur_vec_size_pages = MIN(req_vec_size_pages, (MAX_PAGE_RANGE_QUERY >> PAGE_SHIFT));
 
                first_addr = addr;
        }
index 7d641675d95f77432c127ea0a5028c1345d79a97..37df0b5a0fe80a7811ce89751d0b2917a386a158 100644 (file)
@@ -284,29 +284,6 @@ out_error:
        return NULL;
 }
 
-int persona_invalidate(struct persona *persona)
-{
-       int error = 0;
-       if (!persona)
-               return EINVAL;
-
-       lock_personas();
-       persona_lock(persona);
-
-       if (!persona_valid(persona))
-               panic("Double-invalidation of persona %p", persona);
-
-       LIST_REMOVE(persona, pna_list);
-       if (hw_atomic_add(&g_total_personas, -1) == UINT_MAX)
-               panic("persona ref count underflow!\n");
-       persona_mkinvalid(persona);
-
-       persona_unlock(persona);
-       unlock_personas();
-
-       return error;
-}
-
 static struct persona *persona_get_locked(struct persona *persona)
 {
        if (persona->pna_refcount) {
@@ -353,12 +330,14 @@ void persona_put(struct persona *persona)
 
        /* remove it from the global list and decrement the count */
        lock_personas();
+       persona_lock(persona);
        if (persona_valid(persona)) {
                LIST_REMOVE(persona, pna_list);
                if (hw_atomic_add(&g_total_personas, -1) == UINT_MAX)
                        panic("persona count underflow!\n");
                persona_mkinvalid(persona);
        }
+       persona_unlock(persona);
        unlock_personas();
 
        assert(LIST_EMPTY(&persona->pna_members));
@@ -398,6 +377,34 @@ struct persona *persona_lookup(uid_t id)
        return persona;
 }
 
+struct persona *persona_lookup_and_invalidate(uid_t id)
+{
+       struct persona *persona, *entry, *tmp;
+
+       persona = NULL;
+
+       lock_personas();
+       LIST_FOREACH_SAFE(entry, &all_personas, pna_list, tmp) {
+               persona_lock(entry);
+               if (entry->pna_id == id) {
+                       if (persona_valid(entry)) {
+                               persona = persona_get_locked(entry);
+                               assert(persona != NULL);
+                               LIST_REMOVE(persona, pna_list);
+                               if (hw_atomic_add(&g_total_personas, -1) == UINT_MAX)
+                                       panic("persona ref count underflow!\n");
+                               persona_mkinvalid(persona);
+                       }
+                       persona_unlock(entry);
+                       break;
+               }
+               persona_unlock(entry);
+       }
+       unlock_personas();
+
+       return persona;
+}
+
 int persona_find(const char *login, uid_t uid,
                 struct persona **persona, size_t *plen)
 {
index 249d8c3553db97e05dd327b1e416b8b5d2ade481..f25390cb4955603dee16b057aefcf616a0db4d0d 100644 (file)
@@ -184,11 +184,13 @@ __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN+1] = {"/cores/core.%P"};
 #include <kern/backtrace.h>
 #endif
 
+typedef uint64_t unaligned_u64 __attribute__((aligned(1)));
+
 static void orphanpg(struct pgrp * pg);
 void proc_name_kdp(task_t t, char * buf, int size);
 void * proc_get_uthread_uu_threadlist(void * uthread_v);
 int proc_threadname_kdp(void * uth, char * buf, size_t size);
-void proc_starttime_kdp(void * p, uint64_t * tv_sec, uint64_t * tv_usec, uint64_t * abstime);
+void proc_starttime_kdp(void * p, unaligned_u64 *tv_sec, unaligned_u64 *tv_usec, unaligned_u64 *abstime);
 char * proc_name_address(void * p);
 
 /* TODO: make a header that's exported and usable in osfmk */
@@ -915,23 +917,20 @@ proc_threadname_kdp(void * uth, char * buf, size_t size)
        return 0;
 }
 
+
 /* note that this function is generally going to be called from stackshot,
  * and the arguments will be coming from a struct which is declared packed
  * thus the input arguments will in general be unaligned. We have to handle
  * that here. */
 void
-proc_starttime_kdp(void *p, uint64_t *tv_sec, uint64_t *tv_usec, uint64_t *abstime)
+proc_starttime_kdp(void *p, unaligned_u64 *tv_sec, unaligned_u64 *tv_usec, unaligned_u64 *abstime)
 {
        proc_t pp = (proc_t)p;
-       struct uint64p {
-               uint64_t val;
-       } __attribute__((packed));
-
        if (pp != PROC_NULL) {
                if (tv_sec != NULL)
-                       ((struct uint64p *)tv_sec)->val = pp->p_start.tv_sec;
+                       *tv_sec = pp->p_start.tv_sec;
                if (tv_usec != NULL)
-                       ((struct uint64p *)tv_usec)->val = pp->p_start.tv_usec;
+                       *tv_usec = pp->p_start.tv_usec;
                if (abstime != NULL) {
                        if (pp->p_stats != NULL)
                                *abstime = pp->p_stats->ps_start;
index 2be1a131061266b2651cc6e5e2a1f2155d0ef8ee..48f9128005f977f12234a8277002b99c16126792 100644 (file)
@@ -68,6 +68,7 @@
 #include <sys/sysproto.h>              /* abused for sync() */
 #include <kern/clock.h>                        /* for delay_for_interval() */
 #include <libkern/OSAtomic.h>
+#include <IOKit/IOPlatformExpert.h>
 
 #include <sys/kdebug.h>
 
@@ -83,7 +84,6 @@ static int  sd_closelog(vfs_context_t);
 static void sd_log(vfs_context_t, const char *, ...);
 static void proc_shutdown(void);
 static void kernel_hwm_panic_info(void);
-extern void IOSystemShutdownNotification(void);
 extern void halt_log_enter(const char * what, const void * pc, uint64_t time);
 
 #if DEVELOPMENT || DEBUG
@@ -157,10 +157,9 @@ reboot_kernel(int howto, char *message)
                return (EBUSY);
        }
        /*
-        * Temporary hack to notify the power management root domain
-        * that the system will shut down.
+        * Notify the power management root domain that the system will shut down.
         */
-       IOSystemShutdownNotification();
+       IOSystemShutdownNotification(kIOSystemShutdownNotificationStageProcessExit);
 
        if ((howto&RB_QUICK)==RB_QUICK) {
                printf("Quick reboot...\n");
@@ -201,6 +200,8 @@ reboot_kernel(int howto, char *message)
                        halt_log_enter("shutdown.trace", 0, mach_absolute_time() - startTime);
                }
 
+               IOSystemShutdownNotification(kIOSystemShutdownNotificationStageRootUnmount);
+
                /*
                 * Unmount filesystems
                 */
index d390ded07a4aaed8a46919d4e3851ef2694bb854..849562ccaf2890333013775d13fee33926babb84 100644 (file)
@@ -140,7 +140,8 @@ extern void doexception(int exc, mach_exception_code_t code,
                mach_exception_subcode_t sub);
 
 static void stop(proc_t, proc_t);
-int cansignal(proc_t, kauth_cred_t, proc_t, int, int);
+static int cansignal_nomac(proc_t, kauth_cred_t, proc_t, int);
+int cansignal(proc_t, kauth_cred_t, proc_t, int);
 int killpg1(proc_t, int, int, int, int);
 kern_return_t do_bsdexception(int, int, int);
 void __posix_sem_syscall_return(kern_return_t);
@@ -168,19 +169,18 @@ SECURITY_READ_ONLY_EARLY(struct filterops) sig_filtops = {
 
 /* structures  and fns for killpg1 iterartion callback and filters */
 struct killpg1_filtargs {
-       int  posix;
-       proc_t cp;
+       bool posix;
+       proc_t curproc;
 };
 
 struct killpg1_iterargs {
-       proc_t cp;
+       proc_t curproc;
        kauth_cred_t uc;
        int signum;
-       int * nfoundp;
-       int zombie;
+       int nfound;
 };
 
-static int killpg1_filt(proc_t p, void * arg);
+static int killpg1_allfilt(proc_t p, void * arg);
 static int killpg1_pgrpfilt(proc_t p, __unused void * arg);
 static int killpg1_callback(proc_t p, void * arg);
 
@@ -291,75 +291,87 @@ signal_setast(thread_t sig_actthread)
        act_set_astbsd(sig_actthread);
 }
 
-/*
- * Can process p, with ucred uc, send the signal signum to process q?
- * uc is refcounted  by the caller so internal fileds can be used safely
- * when called with zombie arg, list lock is held
- */
-int
-cansignal(proc_t p, kauth_cred_t uc, proc_t q, int signum, int zombie)
+static int
+cansignal_nomac(proc_t src, kauth_cred_t uc_src, proc_t dst, int signum)
 {
-       kauth_cred_t my_cred;
-       struct session * p_sessp = SESSION_NULL;
-       struct session * q_sessp = SESSION_NULL;
-#if CONFIG_MACF
-       int error;
-
-       error = mac_proc_check_signal(p, q, signum);
-       if (error)
-               return (0);
-#endif
-
        /* you can signal yourself */
-       if (p == q)
-               return(1);
+       if (src == dst) {
+               return 1;
+       }
 
-       /* you can't send launchd SIGKILL, even if root */
-       if (signum == SIGKILL && q == initproc)
-               return(0);
+       /* you can't send the init proc SIGKILL, even if root */
+       if (signum == SIGKILL && dst == initproc) {
+               return 0;
+       }
 
-       if (!suser(uc, NULL))
-               return (1);             /* root can always signal */
+        /* otherwise, root can always signal */
+       if (kauth_cred_issuser(uc_src)) {
+               return 1;
+       }
 
-       if (zombie == 0)
+       /* processes in the same session can send SIGCONT to each other */
+       {
+               struct session *sess_src = SESSION_NULL;
+               struct session *sess_dst = SESSION_NULL;
+
+               /* The session field is protected by the list lock. */
                proc_list_lock();
-       if (p->p_pgrp != PGRP_NULL)
-               p_sessp = p->p_pgrp->pg_session;
-       if (q->p_pgrp != PGRP_NULL)
-               q_sessp = q->p_pgrp->pg_session;
+               if (src->p_pgrp != PGRP_NULL) {
+                       sess_src = src->p_pgrp->pg_session;
+               }
+               if (dst->p_pgrp != PGRP_NULL) {
+                       sess_dst = dst->p_pgrp->pg_session;
+               }
+               proc_list_unlock();
 
-       if (signum == SIGCONT && q_sessp == p_sessp) {
-               if (zombie == 0)
-                       proc_list_unlock();
-               return (1);             /* SIGCONT in session */
+               /* allow SIGCONT within session and for processes without session */
+               if (signum == SIGCONT && sess_src == sess_dst) {
+                       return 1;
+               }
        }
 
-       if (zombie == 0) 
-               proc_list_unlock();
+       /* the source process must be authorized to signal the target */
+       {
+               int allowed = 0;
+               kauth_cred_t uc_dst = NOCRED, uc_ref = NOCRED;
 
-       /*
-        * If the real or effective UID of the sender matches the real
-        * or saved UID of the target, permit the signal to
-        * be sent.
-        */
-       if (zombie == 0)
-               my_cred = kauth_cred_proc_ref(q);
-       else
-               my_cred = proc_ucred(q);
+               uc_dst = uc_ref = kauth_cred_proc_ref(dst);
 
-       if (kauth_cred_getruid(uc) == kauth_cred_getruid(my_cred) ||
-           kauth_cred_getruid(uc) == kauth_cred_getsvuid(my_cred) ||
-           kauth_cred_getuid(uc) == kauth_cred_getruid(my_cred) ||
-           kauth_cred_getuid(uc) == kauth_cred_getsvuid(my_cred)) {
-               if (zombie == 0)
-                       kauth_cred_unref(&my_cred);
-               return (1);
+               /*
+                * If the real or effective UID of the sender matches the real or saved
+                * UID of the target, allow the signal to be sent.
+                */
+               if (kauth_cred_getruid(uc_src) == kauth_cred_getruid(uc_dst) ||
+                       kauth_cred_getruid(uc_src) == kauth_cred_getsvuid(uc_dst) ||
+                       kauth_cred_getuid(uc_src) == kauth_cred_getruid(uc_dst) ||
+                       kauth_cred_getuid(uc_src) == kauth_cred_getsvuid(uc_dst)) {
+                       allowed = 1;
+               }
+
+               if (uc_ref != NOCRED) {
+                       kauth_cred_unref(&uc_ref);
+                       uc_ref = NOCRED;
+               }
+
+               return allowed;
        }
+}
 
-       if (zombie == 0)
-               kauth_cred_unref(&my_cred);
+/*
+ * Can process `src`, with ucred `uc_src`, send the signal `signum` to process
+ * `dst`?  The ucred is referenced by the caller so internal fileds can be used
+ * safely.
+ */
+int
+cansignal(proc_t src, kauth_cred_t uc_src, proc_t dst, int signum)
+{
+#if CONFIG_MACF
+       if (mac_proc_check_signal(src, dst, signum)) {
+               return 0;
+       }
+#endif
 
-       return (0);
+       return cansignal_nomac(src, uc_src, dst, signum);
 }
 
 /*
@@ -1462,8 +1474,8 @@ kill(proc_t cp, struct kill_args *uap, __unused int32_t *retval)
        kauth_cred_t uc = kauth_cred_get();
        int posix = uap->posix;         /* !0 if posix behaviour desired */
 
-       AUDIT_ARG(pid, uap->pid);
-       AUDIT_ARG(signum, uap->signum);
+       AUDIT_ARG(pid, uap->pid);
+       AUDIT_ARG(signum, uap->signum);
 
        if ((u_int)uap->signum >= NSIG)
                return (EINVAL);
@@ -1472,15 +1484,15 @@ kill(proc_t cp, struct kill_args *uap, __unused int32_t *retval)
                if ((p = proc_find(uap->pid)) == NULL) {
                        if ((p = pzfind(uap->pid)) != NULL) {
                                /*
-                                * IEEE Std 1003.1-2001: return success
-                                * when killing a zombie.
+                                * POSIX 1003.1-2001 requires returning success when killing a
+                                * zombie; see Rationale for kill(2).
                                 */
                                return (0);
                        }
                        return (ESRCH);
                }
                AUDIT_ARG(process, p);
-               if (!cansignal(cp, uc, p, uap->signum, 0)) {
+               if (!cansignal(cp, uc, p, uap->signum)) {
                        proc_rele(p);
                        return(EPERM);
                }
@@ -1490,11 +1502,11 @@ kill(proc_t cp, struct kill_args *uap, __unused int32_t *retval)
                return (0);
        }
        switch (uap->pid) {
-       case -1:                /* broadcast signal */
+       case -1: /* broadcast signal */
                return (killpg1(cp, uap->signum, 0, 1, posix));
-       case 0:                 /* signal own process group */
+       case 0: /* signal own process group */
                return (killpg1(cp, uap->signum, 0, 0, posix));
-       default:                /* negative explicit process group */
+       default: /* negative explicit process group */
                return (killpg1(cp, uap->signum, -(uap->pid), 0, posix));
        }
        /* NOTREACHED */
@@ -1661,7 +1673,7 @@ terminate_with_payload_internal(struct proc *cur_proc, int target_pid, uint32_t
 
        AUDIT_ARG(process, target_proc);
 
-       if (!cansignal(cur_proc, cur_cred, target_proc, SIGKILL, 0)) {
+       if (!cansignal(cur_proc, cur_cred, target_proc, SIGKILL)) {
                proc_rele(target_proc);
                return EPERM;
        }
@@ -1698,108 +1710,85 @@ terminate_with_payload(struct proc *cur_proc, struct terminate_with_payload_args
 }
 
 static int
-killpg1_filt(proc_t p, void * arg)
+killpg1_allfilt(proc_t p, void * arg)
 {
        struct killpg1_filtargs * kfargp = (struct killpg1_filtargs *)arg;
-       proc_t cp = kfargp->cp;
-       int posix = kfargp->posix;
-
 
-       if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
-               (!posix && p == cp))
-               return(0);
-       else
-               return(1);
+       /*
+        * Don't signal initproc, a system process, or the current process if POSIX
+        * isn't specified.
+        */
+       return (p->p_pid > 1 && !(p->p_flag & P_SYSTEM) &&
+                       (kfargp->posix ? true : p != kfargp->curproc));
 }
 
-
 static int
 killpg1_pgrpfilt(proc_t p, __unused void * arg)
 {
-        if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
-                (p->p_stat == SZOMB))
-                return(0);
-        else
-                return(1);
+       /* XXX shouldn't this allow signalling zombies? */
+       return (p->p_pid > 1 && !(p->p_flag & P_SYSTEM) && p->p_stat != SZOMB);
 }
 
-
-
 static int
-killpg1_callback(proc_t p, void * arg)
-{
-       struct killpg1_iterargs * kargp = (struct killpg1_iterargs *)arg;
-        proc_t cp = kargp->cp;
-        kauth_cred_t uc = kargp->uc;   /* refcounted by the caller safe to use internal fields */
-        int signum = kargp->signum;
-       int * nfoundp = kargp->nfoundp;
-       int n;
-       int zombie = 0;
-       int error = 0;
-
-       if ((kargp->zombie != 0) && ((p->p_listflag & P_LIST_EXITED) == P_LIST_EXITED))
-               zombie = 1;
+killpg1_callback(proc_t p, void *arg)
+{
+       struct killpg1_iterargs *kargp = (struct killpg1_iterargs *)arg;
+       int signum = kargp->signum;
 
-       if (zombie != 0) {
-               proc_list_lock();
-               error = cansignal(cp, uc, p, signum, zombie);
-               proc_list_unlock();
-       
-               if (error != 0 && nfoundp != NULL) {
-                       n = *nfoundp;
-                       *nfoundp = n+1;
+       if ((p->p_listflag & P_LIST_EXITED) == P_LIST_EXITED) {
+               /*
+                * Count zombies as found for the purposes of signalling, since POSIX
+                * 1003.1-2001 sees signalling zombies as successful.  If killpg(2) or
+                * kill(2) with pid -1 only finds zombies that can be signalled, it
+                * shouldn't return ESRCH.  See the Rationale for kill(2).
+                *
+                * Don't call into MAC -- it's not expecting signal checks for exited
+                * processes.
+                */
+               if (cansignal_nomac(kargp->curproc, kargp->uc, p, signum)) {
+                       kargp->nfound++;
                }
-       } else {
-               if (cansignal(cp, uc, p, signum, 0) == 0)
-                       return(PROC_RETURNED);
+       } else if (cansignal(kargp->curproc, kargp->uc, p, signum)) {
+               kargp->nfound++;
 
-               if (nfoundp != NULL) {
-                       n = *nfoundp;
-                       *nfoundp = n+1;
-               }
-               if (signum != 0)
+               if (signum != 0) {
                        psignal(p, signum);
+               }
        }
 
-       return(PROC_RETURNED);
+       return PROC_RETURNED;
 }
 
 /*
  * Common code for kill process group/broadcast kill.
- * cp is calling process.
  */
 int
-killpg1(proc_t cp, int signum, int pgid, int all, int posix)
+killpg1(proc_t curproc, int signum, int pgid, int all, int posix)
 {
        kauth_cred_t uc;
        struct pgrp *pgrp;
-       int nfound = 0;
-       struct killpg1_iterargs karg;
-       struct killpg1_filtargs kfarg;
        int error = 0;
-       
-       uc = kauth_cred_proc_ref(cp);
-       if (all) {
-               /* 
-                * broadcast 
-                */
-               kfarg.posix = posix;
-               kfarg.cp = cp;
-
-               karg.cp = cp;
-               karg.uc = uc;
-               karg.nfoundp = &nfound;
-               karg.signum = signum;
-               karg.zombie = 1;
 
-               proc_iterate((PROC_ALLPROCLIST | PROC_ZOMBPROCLIST), killpg1_callback, &karg, killpg1_filt, (void *)&kfarg);
+       uc = kauth_cred_proc_ref(curproc);
+       struct killpg1_iterargs karg = {
+               .curproc = curproc, .uc = uc, .nfound = 0, .signum = signum
+       };
 
+       if (all) {
+               /*
+                * Broadcast to all processes that the user can signal (pid was -1).
+                */
+               struct killpg1_filtargs kfarg = {
+                       .posix = posix, .curproc = curproc
+               };
+               proc_iterate(PROC_ALLPROCLIST | PROC_ZOMBPROCLIST, killpg1_callback,
+                               &karg, killpg1_allfilt, &kfarg);
        } else {
                if (pgid == 0) {
-                       /* 
-                        * zero pgid means send to my process group.
+                       /*
+                        * Send to current the current process' process group.
                         */
-                       pgrp = proc_pgrp(cp);
+                       pgrp = proc_pgrp(curproc);
                 } else {
                        pgrp = pgfind(pgid);
                        if (pgrp == NULL) {
@@ -1808,24 +1797,16 @@ killpg1(proc_t cp, int signum, int pgid, int all, int posix)
                        }
                }
 
-                karg.nfoundp = &nfound;
-                karg.uc = uc;
-                karg.signum = signum;
-               karg.cp = cp;
-               karg.zombie = 0;
-
-
                /* PGRP_DROPREF drops the pgrp refernce */
                pgrp_iterate(pgrp, PGRP_DROPREF, killpg1_callback, &karg,
-                       killpg1_pgrpfilt, NULL);
+                               killpg1_pgrpfilt, NULL);
        }
-       error =  (nfound ? 0 : (posix ? EPERM : ESRCH));
+       error = (karg.nfound > 0 ? 0 : (posix ? EPERM : ESRCH));
 out:
        kauth_cred_unref(&uc);
        return (error);
 }
 
-
 /*
  * Send a signal to a process group.
  */
index 63bcc0443e4d26625ecf997e432aa56b1f216eaf..f6ed41035cc32078d3cd10487e199096c35b3b6c 100644 (file)
@@ -1691,6 +1691,28 @@ SYSCTL_PROC(_kern, KERN_OSVERSION, osversion,
         osversion, 256 /* OSVERSIZE*/, 
         sysctl_osversion, "A", "");
 
+static uint64_t osproductversion_string[48];
+
+STATIC int
+sysctl_osproductversion(__unused struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req)
+{
+       if (req->newptr != 0) {
+               /*
+                * Can only ever be set by launchd, and only once at boot.
+                */
+               if (req->p->p_pid != 1 || osproductversion_string[0] != '\0') {
+                       return EPERM;
+               }
+       }
+
+    return sysctl_handle_string(oidp, arg1, arg2, req);
+}
+
+SYSCTL_PROC(_kern, OID_AUTO, osproductversion,
+        CTLFLAG_RW | CTLFLAG_KERN | CTLTYPE_STRING | CTLFLAG_LOCKED,
+        osproductversion_string, sizeof(osproductversion_string),
+        sysctl_osproductversion, "A", "The ProductVersion from SystemVersion.plist");
+
 static uint64_t osvariant_status = 0;
 
 STATIC int
@@ -1818,6 +1840,10 @@ extern int sched_smt_balance;
 SYSCTL_INT(_kern, OID_AUTO, sched_smt_balance, 
                CTLFLAG_KERN| CTLFLAG_RW| CTLFLAG_LOCKED, 
                &sched_smt_balance, 0, "");
+extern int sched_allow_rt_smt;
+SYSCTL_INT(_kern, OID_AUTO, sched_allow_rt_smt, 
+               CTLFLAG_KERN| CTLFLAG_RW| CTLFLAG_LOCKED, 
+               &sched_allow_rt_smt, 0, "");
 #if __arm__ || __arm64__
 extern uint32_t perfcontrol_requested_recommended_cores;
 SYSCTL_UINT(_kern, OID_AUTO, sched_recommended_cores,
@@ -2193,7 +2219,7 @@ SYSCTL_NODE(_kern_timer, OID_AUTO, longterm, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "lo
 enum {
        THRESHOLD, QCOUNT,
        ENQUEUES, DEQUEUES, ESCALATES, SCANS, PREEMPTS,
-       LATENCY, LATENCY_MIN, LATENCY_MAX, SCAN_LIMIT, PAUSES
+       LATENCY, LATENCY_MIN, LATENCY_MAX, SCAN_LIMIT, SCAN_INTERVAL, PAUSES
 };
 extern uint64_t        timer_sysctl_get(int);
 extern int      timer_sysctl_set(int, uint64_t);
@@ -2221,9 +2247,17 @@ SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, threshold,
 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scan_limit,
                CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
                (void *) SCAN_LIMIT, 0, sysctl_timer, "Q", "");
+SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scan_interval,
+               CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
+               (void *) SCAN_INTERVAL, 0, sysctl_timer, "Q", "");
+
 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, qlen,
                CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
                (void *) QCOUNT, 0, sysctl_timer, "Q", "");
+SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scan_pauses,
+               CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
+               (void *) PAUSES, 0, sysctl_timer, "Q", "");
+
 #if  DEBUG
 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, enqueues,
                CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
@@ -2249,9 +2283,6 @@ SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_min,
 SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, latency_max,
                CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
                (void *) LATENCY_MAX, 0, sysctl_timer, "Q", "");
-SYSCTL_PROC(_kern_timer_longterm, OID_AUTO, scan_pauses,
-               CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
-               (void *) PAUSES, 0, sysctl_timer, "Q", "");
 #endif /* DEBUG */
 
 STATIC int
@@ -3332,37 +3363,6 @@ SYSCTL_PROC(_kern, OID_AUTO, darkboot,
            0, 0, sysctl_darkboot, "I", "");
 #endif
 
-/*
- * This is set by core audio to tell tailspin (ie background tracing) how long
- * its smallest buffer is.  Background tracing can then try to make a reasonable
- * decisions to try to avoid introducing so much latency that the buffers will
- * underflow.
- */
-
-int min_audio_buffer_usec;
-
-STATIC int
-sysctl_audio_buffer SYSCTL_HANDLER_ARGS
-{
-#pragma unused(oidp, arg1, arg2)
-       int err = 0, value = 0, changed = 0;
-       err = sysctl_io_number(req, min_audio_buffer_usec, sizeof(int), &value, &changed);
-       if (err) goto exit;
-
-       if (changed) {
-               /* writing is protected by an entitlement */
-               if (priv_check_cred(kauth_cred_get(), PRIV_AUDIO_LATENCY, 0) != 0) {
-                       err = EPERM;
-                       goto exit;
-               }
-               min_audio_buffer_usec = value;
-       }
-exit:
-       return err;
-}
-
-SYSCTL_PROC(_kern, OID_AUTO, min_audio_buffer_usec, CTLFLAG_RW | CTLFLAG_ANYBODY, 0, 0, sysctl_audio_buffer, "I", "Minimum audio buffer size, in microseconds");
-
 #if DEVELOPMENT || DEBUG
 #include <sys/sysent.h>
 /* This should result in a fatal exception, verifying that "sysent" is
index f84a814cbc6420c2c0d78583e8780bd2e3c7d3af..c63a8d8cde8fcc6b90a0792efc24e803d5db33bb 100644 (file)
 #include <vm/vm_kern.h>
 #include <vm/vm_pager.h>
 #include <vm/vnode_pager.h>
-#include <vm/vm_protos.h> 
+#include <vm/vm_protos.h>
 #include <IOKit/IOReturn.h>    /* for kIOReturnNotPrivileged */
 
 #include <os/overflow.h>
 
+#if __x86_64__
+extern int bootarg_no32exec;    /* bsd_init.c */
+#endif
+
 /*
  * XXX vm/pmap.h should not treat these prototypes as MACH_KERNEL_PRIVATE
  * when KERNEL is defined.
@@ -623,14 +627,20 @@ parse_machfile(
         *      Check to see if right machine type.
         */
        if (((cpu_type_t)(header->cputype & ~CPU_ARCH_MASK) != (cpu_type() & ~CPU_ARCH_MASK)) ||
-           !grade_binary(header->cputype, 
+           !grade_binary(header->cputype,
                header->cpusubtype & ~CPU_SUBTYPE_MASK))
                return(LOAD_BADARCH);
-               
+
+#if __x86_64__
+       if (bootarg_no32exec && (header->cputype == CPU_TYPE_X86)) {
+               return(LOAD_BADARCH_X86);
+       }
+#endif
+
        abi64 = ((header->cputype & CPU_ARCH_ABI64) == CPU_ARCH_ABI64);
-               
+
        switch (header->filetype) {
-       
+
        case MH_EXECUTE:
                if (depth != 1) {
                        return (LOAD_FAILURE);
index d58ae5a4a6fa724097818f00de5b2c2876fe03ab..b564d12017bdd22b2990b232ce993339a5fc0abc 100644 (file)
@@ -63,7 +63,7 @@ typedef struct _load_result {
 
        mach_vm_address_t       all_image_info_addr;
        mach_vm_size_t          all_image_info_size;
-    
+
        int                     thread_count;
        unsigned int
                /* boolean_t */ unixproc        :1,
@@ -104,5 +104,7 @@ load_return_t load_machfile(
 #define        LOAD_IOERROR            9       /* IO error */
 #define        LOAD_DECRYPTFAIL        10      /* FP decrypt failure */
 #define        LOAD_BADMACHO_UPX       11      /* malformed mach-o file */
+#define        LOAD_BADARCH_X86        12      /* -no32exec boot-arg + attempted load
+                                          of 32bit x86 binary */
 
 #endif /* _BSD_KERN_MACH_LOADER_H_ */
index 75b2bb7229d73af996481674deb0450a4b4c2c28..52a91f33bee73c74c3852a4dc7adbb91179854cc 100644 (file)
@@ -471,8 +471,6 @@ const static struct mac_policy_ops policy_ops = {
 
        CHECK_SET_HOOK(iokit_check_set_properties)
 
-       CHECK_SET_HOOK(system_check_chud)
-
        CHECK_SET_HOOK(vnode_check_searchfs)
 
        CHECK_SET_HOOK(priv_check)
index 1f88ae54ef06d0a6779bf402220a24efc2f1c66f..52eaeda02f4dd051cf6f352b738fa1870f843ac5 100644 (file)
@@ -174,6 +174,10 @@ int __attribute__ ((noinline)) proc_pidoriginatorpid_uuid(uuid_t uuid, uint32_t
 int __attribute__ ((noinline)) proc_pidlistuptrs(proc_t p, user_addr_t buffer, uint32_t buffersize, int32_t *retval);
 int __attribute__ ((noinline)) proc_piddynkqueueinfo(pid_t pid, int flavor, kqueue_id_t id, user_addr_t buffer, uint32_t buffersize, int32_t *retval);
 
+#if !CONFIG_EMBEDDED
+int __attribute__ ((noinline)) proc_udata_info(pid_t pid, int flavor, user_addr_t buffer, uint32_t buffersize, int32_t *retval);
+#endif
+
 /* protos for proc_pidfdinfo calls */
 int __attribute__ ((noinline)) pid_vnodeinfo(vnode_t vp, uint32_t vid, struct fileproc * fp,proc_t proc, int fd, user_addr_t  buffer, uint32_t buffersize, int32_t * retval);
 int __attribute__ ((noinline)) pid_vnodeinfopath(vnode_t vp, uint32_t vid, struct fileproc * fp,proc_t proc, int fd, user_addr_t  buffer, uint32_t buffersize, int32_t * retval);
@@ -194,7 +198,7 @@ static void munge_vinfo_stat(struct stat64 *sbp, struct vinfo_stat *vsbp);
 static int proc_piduuidinfo(pid_t pid, uuid_t uuid_buf, uint32_t buffersize);
 int proc_pidpathinfo_internal(proc_t p, __unused uint64_t arg, char *buf, uint32_t buffersize, __unused int32_t *retval);
 
-extern int cansignal(struct proc *, kauth_cred_t, struct proc *, int, int);
+extern int cansignal(struct proc *, kauth_cred_t, struct proc *, int);
 extern int proc_get_rusage(proc_t proc, int flavor, user_addr_t buffer, int is_zombie);
 
 #define CHECK_SAME_USER         TRUE
@@ -272,6 +276,10 @@ proc_info_internal(int callnum, int pid, int flavor, uint64_t arg, user_addr_t b
                        return proc_can_use_foreground_hw(pid, buffer, buffersize, retval);
                case PROC_INFO_CALL_PIDDYNKQUEUEINFO:
                        return proc_piddynkqueueinfo(pid, flavor, (kqueue_id_t)arg, buffer, buffersize, retval);
+#if !CONFIG_EMBEDDED
+               case PROC_INFO_CALL_UDATA_INFO:
+                       return proc_udata_info(pid, flavor, buffer, buffersize, retval);
+#endif /* !CONFIG_EMBEDDED */
                default:
                        return EINVAL;
        }
@@ -2828,7 +2836,7 @@ proc_dirtycontrol(int pid, int flavor, uint64_t arg, int32_t *retval) {
 
                case PROC_DIRTYCONTROL_SET: {                   
                        /* Check privileges; use cansignal() here since the process could be terminated */
-                       if (!cansignal(current_proc(), my_cred, target_p, SIGKILL, 0)) {
+                       if (!cansignal(current_proc(), my_cred, target_p, SIGKILL)) {
                                error = EPERM;
                                goto out;
                        }
@@ -2849,7 +2857,7 @@ proc_dirtycontrol(int pid, int flavor, uint64_t arg, int32_t *retval) {
                
                case PROC_DIRTYCONTROL_CLEAR: {                 
                        /* Check privileges; use cansignal() here since the process could be terminated */
-                       if (!cansignal(current_proc(), my_cred, target_p, SIGKILL, 0)) {
+                       if (!cansignal(current_proc(), my_cred, target_p, SIGKILL)) {
                                error = EPERM;
                                goto out;
                        }
@@ -2912,7 +2920,7 @@ proc_terminate(int pid, int32_t *retval)
 #endif
 
        /* Check privileges; if SIGKILL can be issued, then SIGTERM is also OK */
-       if (!cansignal(current_proc(), uc, p, SIGKILL, 0)) {
+       if (!cansignal(current_proc(), uc, p, SIGKILL)) {
                error = EPERM;
                goto out;
        }
@@ -3206,3 +3214,51 @@ out:
 
        return err;
 }
+
+#if !CONFIG_EMBEDDED
+int
+proc_udata_info(int pid, int flavor, user_addr_t buffer, uint32_t bufsize, int32_t *retval)
+{
+       int err = 0;
+       proc_t p;
+
+       p = proc_find(pid);
+       if (p == PROC_NULL) {
+               return ESRCH;
+       }
+
+       /*
+        * Only support calls against oneself for the moment.
+        */
+       if (p->p_pid != proc_selfpid()) {
+               err = EACCES;
+               goto out;
+       }
+
+       if (bufsize != sizeof (p->p_user_data)) {
+               err = EINVAL;
+               goto out;
+       }
+
+       switch (flavor) {
+       case PROC_UDATA_INFO_SET:
+               err = copyin(buffer, &p->p_user_data, sizeof (p->p_user_data));
+               break;
+       case PROC_UDATA_INFO_GET:
+               err = copyout(&p->p_user_data, buffer, sizeof (p->p_user_data));
+               break;
+       default:
+               err = ENOTSUP;
+               break;
+       }
+
+out:
+       proc_rele(p);
+
+       if (err == 0) {
+               *retval = 0;
+       }
+
+       return err;
+}
+#endif /* !CONFIG_EMBEDDED */
index c8e42fc8c7667693db36a2e402c8cae7e2f09925..66fa1d73e54453322058851d6cbd07dd0336643f 100644 (file)
@@ -146,6 +146,13 @@ pthread_returning_to_userspace(void)
        thread_exception_return();
 }
 
+__attribute__((noreturn))
+static void
+pthread_bootstrap_return(void)
+{
+       thread_bootstrap_return();
+}
+
 static uint32_t
 get_task_threadmax(void) {
        return task_threadmax;
@@ -616,7 +623,7 @@ static const struct pthread_callbacks_s pthread_callbacks = {
        .uthread_is_cancelled = uthread_is_cancelled,
 
        .thread_exception_return = pthread_returning_to_userspace,
-       .thread_bootstrap_return = thread_bootstrap_return,
+       .thread_bootstrap_return = pthread_bootstrap_return,
        .unix_syscall_return = unix_syscall_return,
 
        .absolutetime_to_microtime = absolutetime_to_microtime,
index 65c5975e330bf49ca04467126ec8392730ec9a0b..276dd4b874650bd64f6b0cba6f8b0c40266588c6 100644 (file)
@@ -72,7 +72,7 @@ SYSCTL_NODE(_kern, OID_AUTO, eventhandler, CTLFLAG_RW | CTLFLAG_LOCKED,
 SYSCTL_INT(_kern_eventhandler, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_LOCKED,
     &evh_debug, 0, "Eventhandler debug mode");
 
-struct eventhandler_entry_arg eventhandler_entry_dummy_arg = {{0}};
+struct eventhandler_entry_arg eventhandler_entry_dummy_arg = { { 0 }, { 0 } };
 
 /* List of 'slow' lists */
 static struct eventhandler_lists_ctxt evthdlr_lists_ctxt_glb;
@@ -80,6 +80,12 @@ static lck_grp_attr_t   *eventhandler_mutex_grp_attr;
 static lck_grp_t        *eventhandler_mutex_grp;
 static lck_attr_t       *eventhandler_mutex_attr;
 
+static unsigned int eg_size;   /* size of eventhandler_entry_generic */
+static struct mcache *eg_cache;        /* mcache for eventhandler_entry_generic */
+
+static unsigned int el_size;   /* size of eventhandler_list */
+static struct mcache *el_cache;        /* mcache for eventhandler_list */
+
 static lck_grp_attr_t   *el_lock_grp_attr;
 lck_grp_t        *el_lock_grp;
 lck_attr_t       *el_lock_attr;
@@ -121,6 +127,21 @@ eventhandler_init(void)
        el_lock_attr = lck_attr_alloc_init();
 
        eventhandler_lists_ctxt_init(&evthdlr_lists_ctxt_glb);
+
+       eg_size = sizeof (struct eventhandler_entry_generic);
+       eg_cache = mcache_create("eventhdlr_generic", eg_size,
+           sizeof (uint64_t), 0, MCR_SLEEP);
+
+       el_size = sizeof (struct eventhandler_list);
+       el_cache = mcache_create("eventhdlr_list", el_size,
+           sizeof (uint64_t), 0, MCR_SLEEP);
+}
+
+void
+eventhandler_reap_caches(boolean_t purge)
+{
+       mcache_reap_now(eg_cache, purge);
+       mcache_reap_now(el_cache, purge);
 }
 
 /*
@@ -136,6 +157,8 @@ eventhandler_register_internal(
        struct eventhandler_list                *new_list;
        struct eventhandler_entry               *ep;
 
+       VERIFY(strlen(name) <= (sizeof (new_list->el_name) - 1));
+
        if (evthdlr_lists_ctxt == NULL)
                evthdlr_lists_ctxt = &evthdlr_lists_ctxt_glb;
 
@@ -143,7 +166,7 @@ eventhandler_register_internal(
        VERIFY(epn != NULL); /* cannot register NULL event */
 
        /* lock the eventhandler lists */
-       lck_mtx_lock(&evthdlr_lists_ctxt->eventhandler_mutex);
+       lck_mtx_lock_spin(&evthdlr_lists_ctxt->eventhandler_mutex);
 
        /* Do we need to find/create the (slow) list? */
        if (list == NULL) {
@@ -152,27 +175,16 @@ eventhandler_register_internal(
 
                /* Do we need to create the list? */
                if (list == NULL) {
-                       lck_mtx_unlock(&evthdlr_lists_ctxt->eventhandler_mutex);
-
-                       MALLOC(new_list, struct eventhandler_list *,
-                           sizeof(struct eventhandler_list) + strlen(name) + 1,
-                           M_EVENTHANDLER, M_WAITOK);
-
-                       /* If someone else created it already, then use that one. */
-                       lck_mtx_lock(&evthdlr_lists_ctxt->eventhandler_mutex);
-                       list = _eventhandler_find_list(evthdlr_lists_ctxt, name);
-                       if (list != NULL) {
-                               FREE(new_list, M_EVENTHANDLER);
-                       } else {
-                               evhlog((LOG_DEBUG, "%s: creating list \"%s\"", __func__, name));
-                               list = new_list;
-                               list->el_flags = 0;
-                               list->el_runcount = 0;
-                               bzero(&list->el_lock, sizeof(list->el_lock));
-                               list->el_name = (char *)list + sizeof(struct eventhandler_list);
-                               strlcpy(list->el_name, name, strlen(name) + 1);
-                               TAILQ_INSERT_HEAD(&evthdlr_lists_ctxt->eventhandler_lists, list, el_link);
-                       }
+                       lck_mtx_convert_spin(&evthdlr_lists_ctxt->eventhandler_mutex);
+                       new_list = mcache_alloc(el_cache, MCR_SLEEP);
+                       bzero(new_list, el_size);
+                       evhlog((LOG_DEBUG, "%s: creating list \"%s\"", __func__, name));
+                       list = new_list;
+                       list->el_flags = 0;
+                       list->el_runcount = 0;
+                       bzero(&list->el_lock, sizeof(list->el_lock));
+                       (void) snprintf(list->el_name, sizeof (list->el_name), "%s", name);
+                       TAILQ_INSERT_HEAD(&evthdlr_lists_ctxt->eventhandler_lists, list, el_link);
                }
        }
        if (!(list->el_flags & EHL_INITTED)) {
@@ -210,10 +222,8 @@ eventhandler_register(struct eventhandler_lists_ctxt *evthdlr_lists_ctxt,
        struct eventhandler_entry_generic       *eg;
 
        /* allocate an entry for this handler, populate it */
-       MALLOC(eg, struct eventhandler_entry_generic *,
-           sizeof(struct eventhandler_entry_generic),
-           M_EVENTHANDLER, M_WAITOK | M_ZERO);
-
+       eg = mcache_alloc(eg_cache, MCR_SLEEP);
+       bzero(eg, eg_size);
        eg->func = func;
        eg->ee.ee_arg = arg;
        eg->ee.ee_priority = priority;
@@ -239,7 +249,8 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
                         */
                        if (!TAILQ_EMPTY(&list->el_entries))
                                TAILQ_REMOVE(&list->el_entries, ep, ee_link);
-                       FREE(ep, M_EVENTHANDLER);
+                       EHL_LOCK_CONVERT(list);
+                       mcache_free(eg_cache, ep);
                } else {
                        evhlog((LOG_DEBUG, "%s: marking item %p from \"%s\" as dead", __func__,
                            VM_KERNEL_ADDRPERM(ep), list->el_name));
@@ -250,10 +261,11 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
                if (list->el_runcount == 0) {
                        evhlog((LOG_DEBUG, "%s: removing all items from \"%s\"", __func__,
                            list->el_name));
+                       EHL_LOCK_CONVERT(list);
                        while (!TAILQ_EMPTY(&list->el_entries)) {
                                ep = TAILQ_FIRST(&list->el_entries);
                                TAILQ_REMOVE(&list->el_entries, ep, ee_link);
-                               FREE(ep, M_EVENTHANDLER);
+                               mcache_free(eg_cache, ep);
                        }
                } else {
                        evhlog((LOG_DEBUG, "%s: marking all items from \"%s\" as dead",
@@ -263,7 +275,7 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
                }
        }
        while (list->el_runcount > 0)
-               msleep((caddr_t)list, &list->el_lock, 0, "evhrm", 0);
+               msleep((caddr_t)list, &list->el_lock, PSPIN, "evhrm", 0);
        EHL_UNLOCK(list);
 }
 
@@ -302,10 +314,12 @@ eventhandler_find_list(struct eventhandler_lists_ctxt *evthdlr_lists_ctxt,
                return(NULL);
 
        /* scan looking for the requested list */
-       lck_mtx_lock(&evthdlr_lists_ctxt->eventhandler_mutex);
+       lck_mtx_lock_spin(&evthdlr_lists_ctxt->eventhandler_mutex);
        list = _eventhandler_find_list(evthdlr_lists_ctxt, name);
-       if (list != NULL)
-               EHL_LOCK(list);
+       if (list != NULL) {
+               lck_mtx_convert_spin(&evthdlr_lists_ctxt->eventhandler_mutex);
+               EHL_LOCK_SPIN(list);
+       }
        lck_mtx_unlock(&evthdlr_lists_ctxt->eventhandler_mutex);
 
        return(list);
@@ -325,7 +339,7 @@ eventhandler_prune_list(struct eventhandler_list *list)
        TAILQ_FOREACH_SAFE(ep, &list->el_entries, ee_link, en) {
                if (ep->ee_priority == EHE_DEAD_PRIORITY) {
                        TAILQ_REMOVE(&list->el_entries, ep, ee_link);
-                       FREE(ep, M_EVENTHANDLER);
+                       mcache_free(eg_cache, ep);
                        pruned++;
                }
        }
@@ -350,7 +364,7 @@ eventhandler_lists_ctxt_destroy(struct eventhandler_lists_ctxt *evthdlr_lists_ct
            el_link, list_next) {
                VERIFY(TAILQ_EMPTY(&list->el_entries));
                EHL_LOCK_DESTROY(list);
-               FREE(list, M_EVENTHANDLER);
+               mcache_free(el_cache, list);
        }
        lck_mtx_unlock(&evthdlr_lists_ctxt->eventhandler_mutex);
        lck_mtx_destroy(&evthdlr_lists_ctxt->eventhandler_mutex,
index 792043d8dc9bfa93c0cdf175b3f433c13a991e52..7f33f6769f6eb0789c4ab4abe2001e971e7cea5d 100644 (file)
@@ -144,7 +144,7 @@ out_error:
 
 static int kpersona_dealloc_syscall(user_addr_t idp)
 {
-       int error;
+       int error = 0;
        uid_t persona_id;
        struct persona *persona;
 
@@ -155,19 +155,17 @@ static int kpersona_dealloc_syscall(user_addr_t idp)
        if (error)
                return error;
 
-       persona = persona_lookup(persona_id);
+       /* invalidate the persona (deny subsequent spawn/fork) */
+       persona = persona_lookup_and_invalidate(persona_id);
+
        if (!persona)
                return ESRCH;
 
-       /* invalidate the persona (deny subsequent spawn/fork) */
-       error = persona_invalidate(persona);
-
        /* one reference from the _lookup() */
        persona_put(persona);
 
        /* one reference from the _alloc() */
-       if (!error)
-               persona_put(persona);
+       persona_put(persona);
 
        return error;
 }
index 561a1a0bb3c6ab9e2b345cdfb4a45b296fa83e68..bbfdd5e610547f0411193d8dbec8555b32a9fa4d 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/work_interval.h>
 #include <kern/sched_prim.h>
 #include <kern/thread.h>
+#include <kern/task.h>
 #include <kern/work_interval.h>
 
 #include <libkern/libkern.h>
@@ -46,7 +47,6 @@ work_interval_ctl(__unused proc_t p, struct work_interval_ctl_args *uap,
        kern_return_t   kret = KERN_SUCCESS;
        struct work_interval_notification notification;
 
-       /* Two different structs, because headers are complicated */
        struct work_interval_create_params create_params;
        struct kern_work_interval_create_args create_args;
 
@@ -59,15 +59,12 @@ work_interval_ctl(__unused proc_t p, struct work_interval_ctl_args *uap,
                        if (uap->len < sizeof(create_params))
                                return EINVAL;
 
-                       /*
-                        * Privilege check performed up-front, and then the work
-                        * ID is allocated for use by the thread
-                        */
-                       if ((error = priv_check_cred(kauth_cred_get(), PRIV_WORK_INTERVAL, 0)))
+                       if ((error = copyin(uap->arg, &create_params, sizeof(create_params))))
                                return error;
 
-                       if ((error = copyin(uap->arg, &create_params, sizeof(create_params))))
+                       if ((error = priv_check_cred(kauth_cred_get(), PRIV_WORK_INTERVAL, 0)) != 0) {
                                return error;
+                       }
 
                        create_args = (struct kern_work_interval_create_args) {
                                .wica_id            = create_params.wicp_id,
@@ -95,9 +92,10 @@ work_interval_ctl(__unused proc_t p, struct work_interval_ctl_args *uap,
                                .wicp_create_flags = create_args.wica_create_flags,
                        };
 
-                       if ((error = copyout(&create_params, uap->arg, sizeof(create_params))))
+                       if ((error = copyout(&create_params, uap->arg, sizeof(create_params)))) {
+                               kern_work_interval_destroy(current_thread(), create_args.wica_id);
                                return error;
-
+                       }
                        break;
                case WORK_INTERVAL_OPERATION_DESTROY:
                        if (uap->arg != USER_ADDR_NULL || uap->work_interval_id == 0) {
index 2e174231c2b7e687da63c4a1dfe41d1aa539b557..21efaac4395af8b3649929af06742cfa012e366c 100644 (file)
 0x30A00F8      SMB_smbfs_get_max_access
 0x30A00FC      SMB_smbfs_lookup
 0x30A0100      SMB_smbfs_notify
+0x30B0000      VFS_MountRoot
 0x3110004      OpenThrottleWindow
 0x3110008      CauseIOThrottle
 0x311000C      IO_THROTTLE_DISABLE
 0x531027C      CPUPM_PST_PLIMIT_UIB
 0x5310280      CPUPM_IO
 0x5310284      CPUPM_FI
+0x5310290      CPUPM_URGENCY
+0x5310294      CPUPM_IDLE_EXIT1
+0x5310298      CPUPM_PST_QOS_CONT
 0x5330000      HIBERNATE
 0x5330004      HIBERNATE_WRITE_IMAGE
 0x5330008      HIBERNATE_MACHINE_INIT
 0x7010008      TRACE_STRING_EXEC
 0x701000c      TRACE_STRING_PROC_EXIT
 0x7010010      TRACE_STRING_THREADNAME
+0x7010014      TRACE_STRING_THREADNAME_PREV
 0x7020000      TRACE_PANIC
 0x7020004      TRACE_TIMESTAMPS
 0x7020008      TRACE_LOST_EVENTS
index dac57968b64558c5f9c25cc4cb69e83b94fe9fca..1e1fe83f448d21fbe5df9436326993d83b27b8d7 100644 (file)
@@ -318,7 +318,7 @@ ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
        struct tty_dev_t *driver;
        struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
        struct tty *tp;
-       
+
        if (pti == NULL)
                return (ENXIO);
 
@@ -328,9 +328,16 @@ ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
        save_timeout = tp->t_timeout;
        tp->t_timeout = 60;
 #endif
+       /*
+        * Close the line discipline and backing TTY structures.
+        */
        err = (*linesw[tp->t_line].l_close)(tp, flag);
-       ptsstop(tp, FREAD|FWRITE);
-       (void) ttyclose(tp);
+       (void)ttyclose(tp);
+
+       /*
+        * Flush data and notify any waiters on the master side of this PTY.
+        */
+       ptsstop(tp, FREAD | FWRITE);
 #ifdef FIX_VSX_HANG
        tp->t_timeout = save_timeout;
 #endif
@@ -556,29 +563,46 @@ ptcclose(dev_t dev, __unused int flags, __unused int fmt, __unused proc_t p)
        struct tty_dev_t *driver;
        struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
        struct tty *tp;
+       struct knote *kn;
+
+       if (!pti) {
+               return ENXIO;
+       }
 
-       if (pti == NULL)
-               return (ENXIO);
        tp = pti->pt_tty;
        tty_lock(tp);
 
-       (void)(*linesw[tp->t_line].l_modem)(tp, 0);
-
        /*
-        * XXX MDMBUF makes no sense for ptys but would inhibit the above
-        * l_modem().  CLOCAL makes sense but isn't supported.   Special
-        * l_modem()s that ignore carrier drop make no sense for ptys but
-        * may be in use because other parts of the line discipline make
-        * sense for ptys.  Recover by doing everything that a normal
-        * ttymodem() would have done except for sending a SIGHUP.
+        * XXX MDMBUF makes no sense for PTYs, but would inhibit an `l_modem`.
+        * CLOCAL makes sense but isn't supported.  Special `l_modem`s that ignore
+        * carrier drop make no sense for PTYs but may be in use because other parts
+        * of the line discipline make sense for PTYs.  Recover by doing everything
+        * that a normal `ttymodem` would have done except for sending SIGHUP.
         */
+       (void)(*linesw[tp->t_line].l_modem)(tp, 0);
        if (tp->t_state & TS_ISOPEN) {
                tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
                tp->t_state |= TS_ZOMBIE;
                ttyflush(tp, FREAD | FWRITE);
        }
 
-       tp->t_oproc = 0;                /* mark closed */
+       /*
+        * Null out the backing TTY struct's open procedure to prevent starting
+        * slaves through `ptsstart`.
+        */
+       tp->t_oproc = NULL;
+
+       /*
+        * Clear any select or kevent waiters under the lock.
+        */
+       SLIST_FOREACH(kn, &pti->pt_selr.si_note, kn_selnext) {
+               KNOTE_DETACH(&pti->pt_selr.si_note, kn);
+       }
+       selthreadclear(&pti->pt_selr);
+       SLIST_FOREACH(kn, &pti->pt_selw.si_note, kn_selnext) {
+               KNOTE_DETACH(&pti->pt_selw.si_note, kn);
+       }
+       selthreadclear(&pti->pt_selw);
 
        tty_unlock(tp);
 
index aa583d857b7eb29f8371fabbd3d9ccf6dd1764c6..8e81ab6690cec86036d367aa51d7733802589267 100644 (file)
@@ -823,6 +823,7 @@ ptmx_kqops_common(struct knote *kn, struct ptmx_ioctl *pti, struct tty *tp)
 
        /* disconnects should force a wakeup (EOF) */
        if (!(tp->t_state & TS_CONNECTED)) {
+               kn->kn_flags |= EV_EOF;
                return 1;
        }
 
index ca8fde048190926b5037695bcbfc361cedeca871..c0b0519227b824fba6da95f44c0bd212975deb36 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -93,6 +93,8 @@
 #include <libkern/OSDebug.h>
 #include <libkern/libkern.h>
 
+#include <os/log.h>
+
 #include <IOKit/IOMapper.h>
 
 #include <machine/limits.h>
@@ -634,7 +636,6 @@ typedef struct {
 #define        m_minlimit(c)   mbuf_table[c].mtbl_minlimit
 #define        m_maxlimit(c)   mbuf_table[c].mtbl_maxlimit
 #define        m_wantpurge(c)  mbuf_table[c].mtbl_wantpurge
-#define        m_avgtotal(c)   mbuf_table[c].mtbl_avgtotal
 #define        m_cname(c)      mbuf_table[c].mtbl_stats->mbcl_cname
 #define        m_size(c)       mbuf_table[c].mtbl_stats->mbcl_size
 #define        m_total(c)      mbuf_table[c].mtbl_stats->mbcl_total
@@ -680,6 +681,13 @@ static mbuf_table_t mbuf_table[] = {
 
 #define        NELEM(a)        (sizeof (a) / sizeof ((a)[0]))
 
+
+static uint32_t
+m_avgtotal(mbuf_class_t c)
+{
+       return (mbuf_table[c].mtbl_avgtotal);
+}
+
 static void *mb_waitchan = &mbuf_table;        /* wait channel for all caches */
 static int mb_waiters;                 /* number of waiters */
 
@@ -5304,6 +5312,16 @@ m_pullup(struct mbuf *n, int len)
        int count;
        int space;
 
+       /* check invalid arguments */
+       if (n == NULL) {
+                panic("%s: n == NULL", __func__);
+       }
+       if (len < 0) {
+               os_log_info(OS_LOG_DEFAULT, "%s: failed negative len %d",
+                   __func__, len);
+               goto bad;
+       }
+
        /*
         * If first mbuf has no cluster, and has room for len bytes
         * without shifting current data, pullup into it,
@@ -6527,7 +6545,7 @@ mbuf_sleep(mbuf_class_t class, unsigned int num, int wait)
        mb_waiters++;
        m_region_expand(class) += m_total(class) + num;
        /* wake up the worker thread */
-       if (class > MC_MBUF && mbuf_worker_ready &&
+       if (mbuf_worker_ready &&
            mbuf_worker_needs_wakeup) {
                wakeup((caddr_t)&mbuf_worker_needs_wakeup);
                mbuf_worker_needs_wakeup = FALSE;
@@ -6573,8 +6591,8 @@ mbuf_worker_thread(void)
                        }
                        m_region_expand(MC_CL) = 0;
 
-                       if (n > 0 && freelist_populate(MC_CL, n, M_WAIT) > 0)
-                               mbuf_expand++;
+                       if (n > 0)
+                               freelist_populate(MC_CL, n, M_WAIT);
                }
                if (m_region_expand(MC_BIGCL) > 0) {
                        int n;
@@ -6589,8 +6607,8 @@ mbuf_worker_thread(void)
                        }
                        m_region_expand(MC_BIGCL) = 0;
 
-                       if (n > 0 && freelist_populate(MC_BIGCL, n, M_WAIT) > 0)
-                               mbuf_expand++;
+                       if (n > 0)
+                               freelist_populate(MC_BIGCL, n, M_WAIT);
                }
                if (m_region_expand(MC_16KCL) > 0) {
                        int n;
@@ -6615,13 +6633,11 @@ mbuf_worker_thread(void)
                 * mbufs -- otherwise we could have a large number of useless
                 * clusters allocated.
                 */
-               if (mbuf_expand) {
-                       while (m_total(MC_MBUF) <
-                           (m_total(MC_BIGCL) + m_total(MC_CL))) {
-                               mb_expand_cnt++;
-                               if (freelist_populate(MC_MBUF, 1, M_WAIT) == 0)
-                                       break;
-                       }
+               while (m_total(MC_MBUF) <
+                   (m_total(MC_BIGCL) + m_total(MC_CL) + m_total(MC_16KCL))) {
+                       mb_expand_cnt++;
+                       if (freelist_populate(MC_MBUF, 1, M_WAIT) == 0)
+                               break;
                }
 
                mbuf_worker_needs_wakeup = TRUE;
@@ -8219,20 +8235,23 @@ static int mbtest_running;
 static void mbtest_thread(__unused void *arg)
 {
        int i;
-
+       int scale_down = 1;
+       int iterations = 250;
+       int allocations = nmbclusters;
+       iterations = iterations / scale_down;
+       allocations = allocations / scale_down;
        printf("%s thread starting\n", __func__);
-
-       for (i = 0; i < 1000; i++) {
-               unsigned int needed = 100000;
+       for (i = 0; i < iterations; i++) {
+               unsigned int needed = allocations;
                struct mbuf *m1, *m2, *m3;
 
                if (njcl > 0) {
-                       needed = 100000;
+                       needed = allocations;
                        m3 = m_getpackets_internal(&needed, 0, M_DONTWAIT, 0, M16KCLBYTES);
                        m_freem_list(m3);
                }
 
-               needed = 100000;
+               needed = allocations;
                m2 = m_getpackets_internal(&needed, 0, M_DONTWAIT, 0, MBIGCLBYTES);
                m_freem_list(m2);
 
index fc22ee90453f710a288d4d7bcad0185d4e10b10c..31edbc0ce026a480c5d2dee9a3042caf0cc5a19b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
 struct mbuf *
 m_pulldown(struct mbuf *m, int off, int len, int *offp)
 {
-       struct mbuf *n, *o;
-       int hlen, tlen, olen;
-       int sharedcluster;
+       struct mbuf *n = NULL, *o = NULL;
+       int hlen = 0, tlen = 0, olen = 0;
+       int sharedcluster = 0;
 #if defined(PULLDOWN_STAT) && INET6
        static struct mbuf *prev = NULL;
        int prevlen = 0, prevmlen = 0;
@@ -222,15 +222,24 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
     }
 #endif
        n = m;
+
+       /*
+        * Iterate and make n point to the mbuf
+        * within which the first byte at length
+        * offset is contained from the start of
+        * mbuf chain.
+        */
        while (n != NULL && off > 0) {
                if (n->m_len > off)
                        break;
                off -= n->m_len;
                n = n->m_next;
        }
+
        /* be sure to point non-empty mbuf */
        while (n != NULL && n->m_len == 0)
                n = n->m_next;
+
        if (!n) {
                m_freem(m);
                return NULL;    /* mbuf chain too short */
@@ -239,6 +248,16 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
        /*
         * the target data is on <n, off>.
         * if we got enough data on the mbuf "n", we're done.
+        *
+        * It should be noted, that we should only do this either
+        * when offset is 0, i.e. data is pointing to the start
+        * or when the caller specifies an out argument to get
+        * the offset value in the mbuf to work with data pointer
+        * correctly.
+        *
+        * If offset is not 0 and caller did not provide out-argument
+        * to get offset, we should split the mbuf even when the length
+        * is contained in current mbuf.
         */
        if ((off == 0 || offp) && len <= n->m_len - off)
                goto ok;
@@ -248,12 +267,12 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
 #endif
 
        /*
-        * when len < n->m_len - off and off != 0, it is a special case.
+        * when len <= n->m_len - off and off != 0, it is a special case.
         * len bytes from <n, off> sits in single mbuf, but the caller does
         * not like the starting position (off).
         * chop the current mbuf into two pieces, set off to 0.
         */
-       if (len < n->m_len - off) {
+       if (len <= n->m_len - off) {
                o = m_copym(n, off, n->m_len - off, M_DONTWAIT);
                if (o == NULL) {
                        m_freem(m);
@@ -271,6 +290,8 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
         * we need to take hlen from <n, off> and tlen from <n->m_next, 0>,
         * and construct contiguous mbuf with m_len == len.
         * note that hlen + tlen == len, and tlen > 0.
+        *
+        * Read these variables as head length and tail length
         */
        hlen = n->m_len - off;
        tlen = len - hlen;
@@ -301,6 +322,12 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
                else
                        sharedcluster = 0;
        }
+
+       /*
+        * If we have enough space left in current mbuf to accomodate
+        * tail length, copy tail length worth of data starting with next mbuf
+        * and adjust the length of next one accordingly.
+        */
        if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen
         && !sharedcluster) {
                m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len);
@@ -308,8 +335,15 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
                m_adj(n->m_next, tlen);
                goto ok;
        }
-       if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen
-        && !sharedcluster) {
+
+       /*
+        * If have enough leading space in next mbuf to accomodate head length
+        * of current mbuf, and total resulting length of next mbuf is greater
+        * than or equal to requested len bytes, then just copy hlen from
+        * current to the next one and adjust sizes accordingly.
+        */
+       if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen &&
+           (n->m_next->m_len + hlen) >= len && !sharedcluster) {
                n->m_next->m_data -= hlen;
                n->m_next->m_len += hlen;
                bcopy(mtod(n, caddr_t) + off, mtod(n->m_next, caddr_t), hlen);
index 7d744eff9154492e400b006ead6cdc06088fdd74..bd6b3030f6f2fdbfac9726b761ce4024220346b1 100644 (file)
@@ -5128,6 +5128,15 @@ sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock)
                                so->so_flags |= SOF_PRIVILEGED_TRAFFIC_CLASS;
                        break;
 
+#if (DEVELOPMENT || DEBUG)
+               case SO_DEFUNCTIT:
+                       error = sosetdefunct(current_proc(), so, 0, FALSE);
+                       if (error == 0)
+                               error = sodefunct(current_proc(), so, 0);
+
+                       break;
+#endif /* (DEVELOPMENT || DEBUG) */
+
                case SO_DEFUNCTOK:
                        error = sooptcopyin(sopt, &optval, sizeof (optval),
                            sizeof (optval));
index ce89864cc3337d1ed2a03b044bd3931522feb673..87d06ad39955b4ada649aaf5a1079655b137eb08 100644 (file)
@@ -1434,7 +1434,7 @@ sbappendstream_rcvdemux(struct socket *so, struct mbuf *m, uint32_t seqnum,
                ret = sbappendmsgstream_rcv(&so->so_rcv, m, seqnum, unordered);
        }
 #if MPTCP
-       else if (so->so_flags & SOF_MPTCP_TRUE) {
+       else if (so->so_flags & SOF_MP_SUBFLOW) {
                ret = sbappendmptcpstream_rcv(&so->so_rcv, m);
        }
 #endif /* MPTCP */
@@ -1457,8 +1457,8 @@ sbappendmptcpstream_rcv(struct sockbuf *sb, struct mbuf *m)
 
        if (m == NULL || m_pktlen(m) == 0 || (sb->sb_flags & SB_DROP) ||
            (so->so_state & SS_CANTRCVMORE)) {
-               if (m && m_pktlen(m) == 0 &&
-                   (m->m_flags & M_PKTHDR) &&
+               if (m && (m->m_flags & M_PKTHDR) &&
+                   m_pktlen(m) == 0 &&
                    (m->m_pkthdr.pkt_flags & PKTF_MPTCP_DFIN)) {
                        mptcp_input(tptomptp(sototcpcb(so))->mpt_mpte, m);
                        return (1);
index d0358dd0d1990265928ea563182088e15223bbc7..9424dee8762adcfe0824f68a830da62939eb8af0 100644 (file)
@@ -1,15 +1,29 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2016-2018 Apple Inc. All rights reserved.
  *
- * This document is the property of Apple Inc.
- * It is considered confidential and proprietary.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * This document may not be reproduced or transmitted in any form,
- * in whole or in part, without the express written permission of
- * Apple Inc.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  *
- * CRC-16-ANSI (aka CRC-16-IBM) Polynomial: x^16 + x^15 + x^2 + 1
- * Derived from Craig Marciniak's "Craig's Portable CRC16 Library."
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <sys/systm.h>
@@ -62,3 +76,17 @@ crc16(uint16_t crc, const void *buf, size_t size)
 
     return crc;
 }
+
+#if KASAN
+uint16_t
+__nosan_crc16(uint16_t crc, const void *buf, size_t size)
+{
+       const uint8_t *p = buf;
+
+       while (size--) {
+               crc = crc16_tab[(crc ^ (*p++)) & 0xFF] ^ (crc >> 8);
+       }
+
+       return crc;
+}
+#endif
index e2a47fdefef1ed617f553b3d16b7f2f190e00e1c..fa8317325e493498ece6e0f33e8b9040f546c473 100644 (file)
@@ -179,6 +179,15 @@ int        _consume_printf_args(int, ...);
 uint16_t       crc16(uint16_t crc, const void *bufp, size_t len);
 uint32_t       crc32(uint32_t crc, const void *bufp, size_t len);
 
+#if XNU_KERNEL_PRIVATE
+#if KASAN
+uint16_t __nosan_crc16(uint16_t crc, const void *bufp, size_t len);
+#else
+static inline uint16_t
+__nosan_crc16(uint16_t crc, const void *bufp, size_t len) { return crc16(crc, bufp, len); }
+#endif
+#endif
+
 int    copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done);
 int    copyinstr(const user_addr_t uaddr, void *kaddr, size_t len, size_t *done);
 int    copyoutstr(const void *kaddr, user_addr_t udaddr, size_t len, size_t *done);
@@ -229,6 +238,20 @@ clz(unsigned int num)
 #endif
 }
 
+#if XNU_KERNEL_PRIVATE
+
+/*
+ * Define a function that for whatever reason needs to exist, but must never be
+ * called.
+ */
+#define UNSUPPORTED_API(funcname, ...) \
+       _Pragma("clang diagnostic push") \
+       _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
+       funcname(__VA_ARGS__) { panic(__func__ ": unsupported API\n"); } \
+       _Pragma("clang diagnostic pop")
+
+#endif
+
 __END_DECLS
 
 #endif /* _LIBKERN_LIBKERN_H_ */
index b55972bd918aa12974e544e58f703fe6661998bf..0ea25179c6e033869a4df1192cc15d16f39b8b8e 100644 (file)
@@ -56,7 +56,7 @@
 .\"
 .\"     @(#)fcntl.2    8.2 (Berkeley) 1/12/94
 .\"
-.Dd February 17, 2011
+.Dd August 24, 2017
 .Dt FCNTL 2
 .Os BSD 4.2
 .Sh NAME
@@ -153,8 +153,10 @@ The argument must be a buffer of size
 or greater.
 .It Dv F_PREALLOCATE
 Preallocate file storage space. Note: upon success, 
-the space that is allocated can be the same size or 
-larger than the space requested.
+the space that is allocated can be the size requested,
+larger than the size requested, or (if the
+.Dv F_ALLOCATEALL
+flag is not provided) smaller than the space requested.
 .It Dv F_PUNCHHOLE
 Deallocate a region and replace it with a hole. Subsequent reads of the
 affected region will return bytes of zeros that are usually not backed by
@@ -779,6 +781,31 @@ or
 and satisfying the lock or unlock request would result in the
 number of locked regions in the system exceeding a system-imposed limit.
 .\" ==========
+.It Bq Er ENOSPC
+The argument
+.Fa cmd
+is
+.Dv F_PREALLOCATE
+and either there is no space available on the volume containing
+.Fa fildes
+or
+.Fa fst_flags
+contains
+.Dv F_ALLOCATEALL
+and there is not enough space available on the volume containing
+.Fa fildes
+to satisfy the entire request.
+.Pp
+The argument
+.Fa cmd
+is
+.Dv F_PUNCHHOLE
+and there is not enough space available on the volume containing
+.Fa fildes
+to satisfy the request. As an example, a filesystem that supports
+cloned files may return this error if punching a hole requires the
+creation of a clone and there is not enough space available to do so.
+.\" ==========
 .It Bq Er EOVERFLOW
 A return value would overflow its representation.
 For example,
@@ -788,6 +815,11 @@ and the smallest (or, if l_len is non-zero, the largest) offset
 of a byte in the requested segment
 will not fit in an object of type off_t.
 .\" ==========
+.It Bq Er EPERM
+The argument cmd is
+.Dv F_PUNCHHOLE
+and the calling process does not have file write permission.
+.\" ==========
 .It Bq Er ESRCH
 .Fa Cmd
 is
index 57e3b3d344f25c43e54aa8a2e5e1d14f969444d4..d9b740f6751d7a6e1299c58b9cfbb14974526764 100644 (file)
@@ -48,9 +48,9 @@
 The
 .Fn fs_snapshot_create
 function, for supported Filesystems, causes a snapshot  of the Filesystem to be created. A snapshot is a read only copy
-of the filesystem frozen at a point in time.  The Filesystem is identified by the the
+of the filesystem frozen at a point in time.  The Filesystem is identified by the
 .Fa dirfd
-parameter which should be a file descriptor associated with the root directory of the filesystem for the snapshot is to be created.
+parameter which should be a file descriptor associated with the root directory of the filesystem for which the snapshot is to be created.
 .Fa name
 can be any valid name for a component name (except . and ..).
 .
@@ -94,11 +94,13 @@ Upon successful completion,
 .Fn fs_snapshot_create
 ,
 .Fn fs_snapshot_delete
-,
-.Fn fs_snapshot_rename
 and
-.Fn fs_snapshot_list
+.Fn fs_snapshot_rename
 returns 0. Otherwise, a value of -1 is returned and errno is set to indicate the error.
+.Fn fs_snapshot_list
+returns the number of entries successfully read. A return value of 0 indicates there are no more entries.
+Otherwise, a value of -1 is returned and errno is set to indicate the error. Return values are the same as
+.Xr getattrlistbulk 2 .
 .Pp
 .Sh COMPATIBILITY 
 Not all volumes support snapshots. A volume can be tested for snapshot support
index 4c7b0ede81c0edeb8cdb1b4faea674d501489acc..aaf91dd5aa93f137092fd9f2e916c313c4893f9a 100644 (file)
@@ -39,6 +39,9 @@ each directory entry like
 Note: when
 .Fn getattrlistbulk
 returns information about a symbolic link, the information returned is about the link itself, not the target of the link.
+The order of the directory entries (and their associated metadata) vended by
+.Fn getattrlistbulk
+is not specified.  Some file systems may return entries in lexicographic sort order and others may not.
 .Pp
 The function reads directory entries from the directory referenced by the file
 descriptor 
index 7e04d0df594dd2ff9219fc48e1c8eb3dd5603e3d..f465c57901a8f9248743d9ef80f8fe3835f58205 100644 (file)
@@ -68,7 +68,11 @@ with buffers smaller than this size.
 The data in the buffer is a series of
 .Em dirent
 structures (see
-.Xr dir 5 )
+.Xr dir 5)
+The order of the directory entries vended out via 
+.Fn getdirentries
+is not specified. Some filesystems may return entries in lexicographic sort order
+and others may not. 
 .Pp
 The
 .Fa d_fileno
index 11c3ac25e08a83dac9d00c78120647bdd9159c49..6e0c09d1cf99dfb8020bb5fa70aa750995039c8b 100644 (file)
@@ -1925,6 +1925,11 @@ void throttle_set_thread_io_policy(int policy)
        proc_set_thread_policy(current_thread(), TASK_POLICY_INTERNAL, TASK_POLICY_IOPOL, policy);
 }
 
+int throttle_get_thread_effective_io_policy()
+{
+       return proc_get_effective_thread_policy(current_thread(), TASK_POLICY_IO);
+}
+
 void throttle_info_reset_window(uthread_t ut)
 {
        struct _throttle_io_info_t *info;
@@ -2709,21 +2714,35 @@ spec_knote_select_and_link(struct knote *kn)
        rlptr = (void *)&rsvd_arg;
 
        /*
-        * Trick selrecord() into hooking kqueue's wait queue set
-        * set into device's selinfo wait queue
+        * Trick selrecord() into hooking kqueue's wait queue set into the device's
+        * selinfo wait queue.
         */
        old_wqs = uth->uu_wqset;
        uth->uu_wqset = &(knote_get_kq(kn)->kq_wqs);
+       /*
+        * Now these are the laws of VNOP_SELECT, as old and as true as the sky,
+        * And the device that shall keep it may prosper, but the device that shall
+        * break it must receive ENODEV:
+        *
+        * 1. Take a lock to protect against other selects on the same vnode.
+        * 2. Return 1 if data is ready to be read.
+        * 3. Return 0 and call `selrecord` on a handy `selinfo` structure if there
+        *    is no data.
+        * 4. Call `selwakeup` when the vnode has an active `selrecord` and data
+        *    can be read or written (depending on the seltype).
+        * 5. If there's a `selrecord` and no corresponding `selwakeup`, but the
+        *    vnode is going away, call `selthreadclear`.
+        */
        selres = VNOP_SELECT(vp, knote_get_seltype(kn), 0, rlptr, ctx);
        uth->uu_wqset = old_wqs;
 
        /*
-        * make sure to cleanup the reserved link - this guards against
+        * Make sure to cleanup the reserved link - this guards against
         * drivers that may not actually call selrecord().
         */
        waitq_link_release(rsvd);
        if (rsvd != rsvd_arg) {
-               /* the driver / handler called selrecord() */
+               /* The driver / handler called selrecord() */
                struct waitq *wq;
                memcpy(&wq, rlptr, sizeof(void *));
 
@@ -2748,8 +2767,14 @@ spec_knote_select_and_link(struct knote *kn)
                 * device won't go away while we get this ID.
                 */
                kn->kn_hook_data = waitq_get_prepost_id(wq);
-       } else {
-               assert(selres != 0);
+       } else if (selres == 0) {
+               /*
+                * The device indicated that there's no data to read, but didn't call
+                * `selrecord`.  Nothing will be notified of changes to this vnode, so
+                * return an error back to user space, to make it clear that the knote
+                * is not attached.
+                */
+               knote_set_error(kn, ENODEV);
        }
 
        vnode_put(vp);
index 98db2444f789494deba584350d9a5c8f593901dc..a2e90264fe6c0c25ff64ff021f2b7b8a70f9f78d 100644 (file)
@@ -46,6 +46,7 @@ PRIVATE_DATAFILES = \
        if_media.h \
        if_mib.h \
        if_pflog.h \
+       if_ports_used.h \
        if_ppp.h \
        if_utun.h \
        if_var.h \
index 1448fc02b576f73643ea03e8a02f33e57e38b323..70b69823b3d28d94dc940f8b822bf45470fe8315 100644 (file)
@@ -547,6 +547,7 @@ bpf_detachd(struct bpf_d *d, int closing)
        struct bpf_if *bp;
        struct ifnet  *ifp;
 
+       int bpf_closed = d->bd_flags & BPF_CLOSING;
        /*
         * Some other thread already detached
         */
@@ -615,6 +616,9 @@ bpf_detachd(struct bpf_d *d, int closing)
         */
        d->bd_flags &= ~BPF_DETACHING;
        d->bd_flags |= BPF_DETACHED;
+
+       /* Refresh the local variable as d could have been modified */
+       bpf_closed = d->bd_flags & BPF_CLOSING;
        /*
         * Note that We've kept the reference because we may have dropped
         * the lock when turning off promiscuous mode
@@ -631,7 +635,7 @@ done:
        /*
         * Let the caller know the bpf_d is closed
         */
-       if ((d->bd_flags & BPF_CLOSING))
+       if (bpf_closed)
                return (1);
        else
                return (0);
@@ -1508,7 +1512,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, __unused int flags,
         * Set buffer length.
         */
        case BIOCSBLEN:                 /* u_int */
-               if (d->bd_bif != 0)
+               if (d->bd_bif != 0 || (d->bd_flags & BPF_DETACHING))
                        error = EINVAL;
                else {
                        u_int size;
@@ -2585,6 +2589,9 @@ catchpacket(struct bpf_d *d, struct bpf_packet * pkt,
        if (totlen > d->bd_bufsize)
                totlen = d->bd_bufsize;
 
+       if (hdrlen > totlen)
+               return;
+
        /*
         * Round up the end of the previous packet to the next longword.
         */
index f762add426f9cb96a64e70ff838af47217d61fe4..f004be34074b36a72180754388db4f9fb97a500c 100644 (file)
@@ -47,7 +47,8 @@
 #include <net/pktsched/pktsched_fq_codel.h>
 #include <net/classq/classq_fq_codel.h>
 
-static struct zone *flowq_zone = NULL;
+static uint32_t flowq_size;                    /* size of flowq */
+static struct mcache *flowq_cache = NULL;      /* mcache for flowq */
 
 #define        FQ_ZONE_MAX     (32 * 1024)     /* across all interfaces */
 
@@ -58,30 +59,35 @@ static struct zone *flowq_zone = NULL;
 void
 fq_codel_init(void)
 {
-       if (flowq_zone != NULL)
+       if (flowq_cache != NULL)
                return;
 
-       flowq_zone = zinit(sizeof (struct flowq),
-           FQ_ZONE_MAX * sizeof (struct flowq), 0, "flowq_zone");
-       if (flowq_zone == NULL) {
-               panic("%s: failed to allocate flowq_zone", __func__);
+       flowq_size = sizeof (fq_t);
+       flowq_cache = mcache_create("fq.flowq", flowq_size, sizeof (uint64_t),
+           0, MCR_SLEEP);
+       if (flowq_cache == NULL) {
+               panic("%s: failed to allocate flowq_cache", __func__);
                /* NOTREACHED */
        }
-       zone_change(flowq_zone, Z_EXPAND, TRUE);
-       zone_change(flowq_zone, Z_CALLERACCT, TRUE);
+}
+
+void
+fq_codel_reap_caches(boolean_t purge)
+{
+       mcache_reap_now(flowq_cache, purge);
 }
 
 fq_t *
 fq_alloc(classq_pkt_type_t ptype)
 {
        fq_t *fq = NULL;
-       fq = zalloc(flowq_zone);
+       fq = mcache_alloc(flowq_cache, MCR_SLEEP);
        if (fq == NULL) {
-               log(LOG_ERR, "%s: unable to allocate from flowq_zone\n");
+               log(LOG_ERR, "%s: unable to allocate from flowq_cache\n");
                return (NULL);
        }
 
-       bzero(fq, sizeof (*fq));
+       bzero(fq, flowq_size);
        fq->fq_ptype = ptype;
        if (ptype == QP_MBUF) {
                MBUFQ_INIT(&fq->fq_mbufq);
@@ -95,7 +101,7 @@ fq_destroy(fq_t *fq)
        VERIFY(fq_empty(fq));
        VERIFY(!(fq->fq_flags & (FQF_NEW_FLOW | FQF_OLD_FLOW)));
        VERIFY(fq->fq_bytes == 0);
-       zfree(flowq_zone, fq);
+       mcache_free(flowq_cache, fq);
 }
 
 static void
index 6683256c1bc48914d983a1c5299f872cd08cf871..6db259bb7845509109fbcaa119298c739e6456a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2016-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -87,6 +87,7 @@ struct fq_if_classq;
 
 /* Function definitions */
 extern void fq_codel_init(void);
+extern void fq_codel_reap_caches(boolean_t);
 extern fq_t *fq_alloc(classq_pkt_type_t);
 extern void fq_destroy(fq_t *);
 extern int fq_addq(struct fq_codel_sched_data *, pktsched_pkt_t *,
index 669e45ad693be9f0c768ce5c64af784932cc6677..7c93bc65ec2c92dd8c90322bfdf28fac18ac28a6 100644 (file)
@@ -41,6 +41,7 @@
 #include <net/classq/classq.h>
 #include <pexpert/pexpert.h>
 #include <net/classq/classq_sfb.h>
+#include <net/classq/classq_fq_codel.h>
 #include <net/pktsched/pktsched.h>
 #include <net/pktsched/pktsched_fq_codel.h>
 
@@ -793,3 +794,9 @@ ifclassq_calc_update_interval(u_int64_t *update_interval)
 
        *update_interval = uint;
 }
+
+void
+ifclassq_reap_caches(boolean_t purge)
+{
+       fq_codel_reap_caches(purge);
+}
index 1484269030b059493d82ab7aa2edd22ecac1f2b2..18e9bc7f8c1ab79846156487baf45b8e7efc002e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -365,6 +365,7 @@ extern void ifclassq_calc_target_qdelay(struct ifnet *ifp,
 extern void ifclassq_calc_update_interval(u_int64_t *update_interval);
 extern void ifclassq_set_packet_metadata(struct ifclassq *ifq,
     struct ifnet *ifp, void *p, classq_pkt_type_t ptype);
+extern void ifclassq_reap_caches(boolean_t);
 
 #endif /* BSD_KERNEL_PRIVATE */
 #endif /* PRIVATE */
index 9219ab940d39e0e77dd72fee2b556b7f61197a7b..c4acddac2aa64a083f501af218b3e7b050b9d4d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -75,6 +75,7 @@
 #include <net/ntstat.h>
 #include <net/if_llatbl.h>
 #include <net/net_api_stats.h>
+#include <net/if_ports_used.h>
 
 #if INET
 #include <netinet/in_var.h>
@@ -322,7 +323,8 @@ static void dlil_if_trace(struct dlil_ifnet *, int);
 static void if_proto_ref(struct if_proto *);
 static void if_proto_free(struct if_proto *);
 static struct if_proto *find_attached_proto(struct ifnet *, u_int32_t);
-static int dlil_ifp_proto_count(struct ifnet *);
+static u_int32_t dlil_ifp_protolist(struct ifnet *ifp, protocol_family_t *list,
+     u_int32_t list_count);
 static void if_flt_monitor_busy(struct ifnet *);
 static void if_flt_monitor_unbusy(struct ifnet *);
 static void if_flt_monitor_enter(struct ifnet *);
@@ -432,7 +434,6 @@ static int sysctl_rcvq_maxlen SYSCTL_HANDLER_ARGS;
 static int sysctl_hwcksum_dbg_mode SYSCTL_HANDLER_ARGS;
 static int sysctl_hwcksum_dbg_partial_rxoff_forced SYSCTL_HANDLER_ARGS;
 static int sysctl_hwcksum_dbg_partial_rxoff_adj SYSCTL_HANDLER_ARGS;
-static int sysctl_get_ports_used SYSCTL_HANDLER_ARGS;
 
 struct chain_len_stats tx_chain_len_stats;
 static int sysctl_tx_chain_len_stats SYSCTL_HANDLER_ARGS;
@@ -519,12 +520,6 @@ struct timespec dlil_dbgrate = { 1, 0 };
 
 SYSCTL_DECL(_net_link_generic_system);
 
-#if CONFIG_MACF
-SYSCTL_INT(_net_link_generic_system, OID_AUTO, dlil_lladdr_ckreq,
-       CTLFLAG_RW | CTLFLAG_LOCKED, &dlil_lladdr_ckreq, 0,
-       "Require MACF system info check to expose link-layer address");
-#endif
-
 SYSCTL_INT(_net_link_generic_system, OID_AUTO, dlil_verbose,
     CTLFLAG_RW | CTLFLAG_LOCKED, &dlil_verbose, 0, "Log DLIL error messages");
 
@@ -734,9 +729,6 @@ uint32_t tx_chain_len_count = 0;
 SYSCTL_UINT(_net_link_generic_system, OID_AUTO, tx_chain_len_count,
     CTLFLAG_RW | CTLFLAG_LOCKED, &tx_chain_len_count, 0, "");
 
-SYSCTL_NODE(_net_link_generic_system, OID_AUTO, get_ports_used,
-    CTLFLAG_RD | CTLFLAG_LOCKED, sysctl_get_ports_used, "");
-
 static uint32_t threshold_notify = 1;          /* enable/disable */
 SYSCTL_UINT(_net_link_generic_system, OID_AUTO, threshold_notify,
     CTLFLAG_RW | CTLFLAG_LOCKED, &threshold_notify, 0, "");
@@ -910,13 +902,24 @@ if_proto_free(struct if_proto *proto)
         */
        ifnet_lock_shared(ifp);
        ev_pr_data.proto_family = proto_family;
-       ev_pr_data.proto_remaining_count = dlil_ifp_proto_count(ifp);
+       ev_pr_data.proto_remaining_count = dlil_ifp_protolist(ifp, NULL, 0);
        ifnet_lock_done(ifp);
 
        dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_PROTO_DETACHED,
            (struct net_event_data *)&ev_pr_data,
            sizeof (struct kev_dl_proto_data));
 
+       if (ev_pr_data.proto_remaining_count == 0) {
+               /*
+                * The protocol count has gone to zero, mark the interface down.
+                * This used to be done by configd.KernelEventMonitor, but that
+                * is inherently prone to races (rdar://problem/30810208).
+                */
+               (void) ifnet_set_flags(ifp, 0, IFF_UP);
+               (void) ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
+               dlil_post_sifflags_msg(ifp);
+       }
+
        zfree(dlif_proto_zone, proto);
 }
 
@@ -1038,12 +1041,20 @@ ifnet_head_assert_exclusive(void)
 }
 
 /*
- * Caller must already be holding ifnet lock.
+ * dlil_ifp_protolist
+ * - get the list of protocols attached to the interface, or just the number
+ *   of attached protocols
+ * - if the number returned is greater than 'list_count', truncation occurred
+ *
+ * Note:
+ * - caller must already be holding ifnet lock.
  */
-static int
-dlil_ifp_proto_count(struct ifnet *ifp)
+static u_int32_t
+dlil_ifp_protolist(struct ifnet *ifp, protocol_family_t *list,
+    u_int32_t list_count)
 {
-       int i, count = 0;
+       u_int32_t       count = 0;
+       int             i;
 
        ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_OWNED);
 
@@ -1053,6 +1064,9 @@ dlil_ifp_proto_count(struct ifnet *ifp)
        for (i = 0; i < PROTO_HASH_SLOTS; i++) {
                struct if_proto *proto;
                SLIST_FOREACH(proto, &ifp->if_proto_hash[i], next_hash) {
+                       if (list != NULL && count < list_count) {
+                               list[count] = proto->protocol_family;
+                       }
                        count++;
                }
        }
@@ -1060,6 +1074,21 @@ done:
        return (count);
 }
 
+__private_extern__ u_int32_t
+if_get_protolist(struct ifnet * ifp, u_int32_t *protolist, u_int32_t count)
+{
+       ifnet_lock_shared(ifp);
+       count = dlil_ifp_protolist(ifp, protolist, count);
+       ifnet_lock_done(ifp);
+       return (count);
+}
+
+__private_extern__ void
+if_free_protolist(u_int32_t *list)
+{
+       _FREE(list, M_TEMP);
+}
+
 __private_extern__ void
 dlil_post_msg(struct ifnet *ifp, u_int32_t event_subclass,
     u_int32_t event_code, struct net_event_data *event_data,
@@ -1684,6 +1713,9 @@ dlil_init(void)
        /* Initialize the service class to dscp map */
        net_qos_map_init();
 
+       /* Initialize the interface port list */
+       if_ports_used_init();
+
 #if DEBUG || DEVELOPMENT
        /* Run self-tests */
        dlil_verify_sum16();
@@ -2697,7 +2729,8 @@ dlil_input_handler(struct ifnet *ifp, struct mbuf *m_head,
        if (inp == dlil_main_input_thread)
                dlil_input_stats_sync(ifp, inp);
 
-       if (qlen(&inp->rcvq_pkts) >= dlil_rcv_mit_pkts_min &&
+       if (inp->input_mit_tcall &&
+           qlen(&inp->rcvq_pkts) >= dlil_rcv_mit_pkts_min &&
            qlen(&inp->rcvq_pkts) < dlil_rcv_mit_pkts_max &&
            (ifp->if_family == IFNET_FAMILY_ETHERNET ||
            ifp->if_type == IFT_CELLULAR)
@@ -4006,6 +4039,27 @@ dlil_post_complete_msg(struct ifnet *ifp, struct kev_msg *event)
        return (kev_post_msg(event));
 }
 
+__private_extern__ void
+dlil_post_sifflags_msg(struct ifnet * ifp)
+{
+       struct kev_msg ev_msg;
+       struct net_event_data ev_data;
+
+       bzero(&ev_data, sizeof (ev_data));
+       bzero(&ev_msg, sizeof (ev_msg));
+       ev_msg.vendor_code = KEV_VENDOR_APPLE;
+       ev_msg.kev_class = KEV_NETWORK_CLASS;
+       ev_msg.kev_subclass = KEV_DL_SUBCLASS;
+       ev_msg.event_code = KEV_DL_SIFFLAGS;
+       strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
+       ev_data.if_family = ifp->if_family;
+       ev_data.if_unit = (u_int32_t) ifp->if_unit;
+       ev_msg.dv[0].data_length = sizeof(struct net_event_data);
+       ev_msg.dv[0].data_ptr = &ev_data;
+       ev_msg.dv[1].data_length = 0;
+       dlil_post_complete_msg(ifp, &ev_msg);
+}
+
 #define        TMP_IF_PROTO_ARR_SIZE   10
 static int
 dlil_event_internal(struct ifnet *ifp, struct kev_msg *event, bool update_generation)
@@ -4048,7 +4102,7 @@ dlil_event_internal(struct ifnet *ifp, struct kev_msg *event, bool update_genera
         * therefore we are avoiding embedded pointers here.
         */
        ifnet_lock_shared(ifp);
-       if_proto_count = dlil_ifp_proto_count(ifp);
+       if_proto_count = dlil_ifp_protolist(ifp, NULL, 0);
        if (if_proto_count) {
                int i;
                VERIFY(ifp->if_proto_hash != NULL);
@@ -5198,7 +5252,8 @@ dlil_attach_protocol_internal(struct if_proto *proto,
         * (subject to change)
         */
        ev_pr_data.proto_family = proto->protocol_family;
-       ev_pr_data.proto_remaining_count = dlil_ifp_proto_count(ifp);
+       ev_pr_data.proto_remaining_count = dlil_ifp_protolist(ifp, NULL, 0);
+
        ifnet_lock_done(ifp);
 
        dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_PROTO_ATTACHED,
@@ -5265,6 +5320,14 @@ end:
        }
        ifnet_head_done();
        if (retval == 0) {
+               /*
+                * A protocol has been attached, mark the interface up.
+                * This used to be done by configd.KernelEventMonitor, but that
+                * is inherently prone to races (rdar://problem/30810208).
+                */
+               (void) ifnet_set_flags(ifp, IFF_UP, IFF_UP);
+               (void) ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
+               dlil_post_sifflags_msg(ifp);
        } else if (ifproto != NULL) {
                zfree(dlif_proto_zone, ifproto);
        }
@@ -5326,6 +5389,14 @@ end:
        }
        ifnet_head_done();
        if (retval == 0) {
+               /*
+                * A protocol has been attached, mark the interface up.
+                * This used to be done by configd.KernelEventMonitor, but that
+                * is inherently prone to races (rdar://problem/30810208).
+                */
+               (void) ifnet_set_flags(ifp, IFF_UP, IFF_UP);
+               (void) ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
+               dlil_post_sifflags_msg(ifp);
        } else if (ifproto != NULL) {
                zfree(dlif_proto_zone, ifproto);
        }
@@ -6705,43 +6776,66 @@ ifp_if_event(struct ifnet *ifp, const struct kev_msg *e)
 #pragma unused(ifp, e)
 }
 
-__private_extern__
 int dlil_if_acquire(u_int32_t family, const void *uniqueid,
-    size_t uniqueid_len, struct ifnet **ifp)
+    size_t uniqueid_len, const char *ifxname, struct ifnet **ifp)
 {
        struct ifnet *ifp1 = NULL;
        struct dlil_ifnet *dlifp1 = NULL;
        void *buf, *base, **pbuf;
        int ret = 0;
 
+       VERIFY(*ifp == NULL);
        dlil_if_lock();
+       /*
+        * We absolutely can't have an interface with the same name
+        * in in-use state.
+        * To make sure of that list has to be traversed completely
+        */
        TAILQ_FOREACH(dlifp1, &dlil_ifnet_head, dl_if_link) {
                ifp1 = (struct ifnet *)dlifp1;
 
                if (ifp1->if_family != family)
                        continue;
 
+               /*
+                * If interface is in use, return EBUSY if either unique id
+                * or interface extended names are the same
+                */
                lck_mtx_lock(&dlifp1->dl_if_lock);
-               /* same uniqueid and same len or no unique id specified */
-               if ((uniqueid_len == dlifp1->dl_if_uniqueid_len) &&
-                   bcmp(uniqueid, dlifp1->dl_if_uniqueid, uniqueid_len) == 0) {
-                       /* check for matching interface in use */
+               if (strncmp(ifxname, ifp1->if_xname, IFXNAMSIZ) == 0) {
                        if (dlifp1->dl_if_flags & DLIF_INUSE) {
-                               if (uniqueid_len) {
-                                       ret = EBUSY;
+                               lck_mtx_unlock(&dlifp1->dl_if_lock);
+                               ret = EBUSY;
+                               goto end;
+                       }
+               }
+
+               if (uniqueid_len) {
+                       if (uniqueid_len == dlifp1->dl_if_uniqueid_len &&
+                           bcmp(uniqueid, dlifp1->dl_if_uniqueid, uniqueid_len) == 0) {
+                               if (dlifp1->dl_if_flags & DLIF_INUSE) {
                                        lck_mtx_unlock(&dlifp1->dl_if_lock);
+                                       ret = EBUSY;
                                        goto end;
+                               } else {
+                                       dlifp1->dl_if_flags |= (DLIF_INUSE|DLIF_REUSE);
+                                       /* Cache the first interface that can be recycled */
+                                       if (*ifp == NULL)
+                                               *ifp = ifp1;
+                                       /*
+                                        * XXX Do not break or jump to end as we have to traverse
+                                        * the whole list to ensure there are no name collisions
+                                        */
                                }
-                       } else {
-                               dlifp1->dl_if_flags |= (DLIF_INUSE|DLIF_REUSE);
-                               lck_mtx_unlock(&dlifp1->dl_if_lock);
-                               *ifp = ifp1;
-                               goto end;
                        }
                }
                lck_mtx_unlock(&dlifp1->dl_if_lock);
        }
 
+       /* If there's an interface that can be recycled, use that */
+       if (*ifp != NULL)
+               goto end;
+
        /* no interface found, allocate a new one */
        buf = zalloc(dlif_zone);
        if (buf == NULL) {
@@ -8660,74 +8754,6 @@ dlil_kev_dl_code_str(u_int32_t event_code)
        return ("");
 }
 
-/*
- * Mirror the arguments of ifnet_get_local_ports_extended()
- *  ifindex
- *  protocol
- *  flags
- */
-static int
-sysctl_get_ports_used SYSCTL_HANDLER_ARGS
-{
-#pragma unused(oidp)
-       int *name = (int *)arg1;
-       int namelen = arg2;
-       int error = 0;
-       int idx;
-       protocol_family_t protocol;
-       u_int32_t flags;
-       ifnet_t ifp = NULL;
-       u_int8_t *bitfield = NULL;
-
-       if (req->newptr != USER_ADDR_NULL) {
-               error = EPERM;
-               goto done;
-       }
-       if (namelen != 3) {
-               error = ENOENT;
-               goto done;
-       }
-
-       if (req->oldptr == USER_ADDR_NULL) {
-               req->oldidx = bitstr_size(65536);
-               goto done;
-       }
-       if (req->oldlen < bitstr_size(65536)) {
-               error = ENOMEM;
-               goto done;
-       }
-
-       idx = name[0];
-       protocol = name[1];
-       flags = name[2];
-
-       ifnet_head_lock_shared();
-       if (!IF_INDEX_IN_RANGE(idx)) {
-               ifnet_head_done();
-               error = ENOENT;
-               goto done;
-       }
-       ifp = ifindex2ifnet[idx];
-       ifnet_head_done();
-
-       bitfield = _MALLOC(bitstr_size(65536), M_TEMP, M_WAITOK | M_ZERO);
-       if (bitfield == NULL) {
-               error = ENOMEM;
-               goto done;
-       }
-       error = ifnet_get_local_ports_extended(ifp, protocol, flags, bitfield);
-       if (error != 0) {
-               printf("%s: ifnet_get_local_ports_extended() error %d\n",
-                   __func__, error);
-               goto done;
-       }
-       error = SYSCTL_OUT(req, bitfield, bitstr_size(65536));
-done:
-       if (bitfield != NULL)
-               _FREE(bitfield, M_TEMP);
-       return (error);
-}
-
 static void
 dlil_dt_tcall_fn(thread_call_param_t arg0, thread_call_param_t arg1)
 {
index 5a6c669e454a326309b8e5a0c96295627a3fcb7b..526e82f46123f0f624c3e2ca8f2db78b930b5d98 100644 (file)
@@ -326,6 +326,8 @@ extern void dlil_proto_unplumb_all(ifnet_t);
 extern void dlil_post_msg(struct ifnet *, u_int32_t, u_int32_t,
     struct net_event_data *, u_int32_t);
 
+extern void dlil_post_sifflags_msg(struct ifnet *);
+
 extern int dlil_post_complete_msg(struct ifnet *, struct kev_msg *);
 
 extern int dlil_alloc_local_stats(struct ifnet *);
@@ -334,7 +336,7 @@ extern int dlil_alloc_local_stats(struct ifnet *);
 /*
  * dlil_if_acquire is obsolete. Use ifnet_allocate.
  */
-extern int dlil_if_acquire(u_int32_t, const void *, size_t, struct ifnet **);
+extern int dlil_if_acquire(u_int32_t, const void *, size_t, const char *, struct ifnet **);
 /*
  * dlil_if_release is obsolete. The equivalent is called automatically when
  * an interface is detached.
index acd1ac75c7a58a0f691393d90ab19863d109c608..33e626245c7d8a04779e83a472f05293e31fbbf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -330,6 +330,7 @@ if_attach_ifa_common(struct ifnet *ifp, struct ifaddr *ifa, int link)
 
        if (ifa->ifa_attached != NULL)
                (*ifa->ifa_attached)(ifa);
+
 }
 
 __private_extern__ void
@@ -696,8 +697,7 @@ if_clone_list(int count, int *ret_total, user_addr_t dst)
        for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
            ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
                bzero(outbuf, sizeof(outbuf));
-               strlcpy(outbuf, ifc->ifc_name,
-                   min(strlen(ifc->ifc_name), IFNAMSIZ));
+               strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
                error = copyout(outbuf, dst, IFNAMSIZ);
                if (error)
                        break;
@@ -1665,7 +1665,8 @@ ifioctl_linkparams(struct ifnet *ifp, u_long cmd, caddr_t data, struct proc *p)
                struct tb_profile tb = { 0, 0, 0 };
 
                if ((error = proc_suser(p)) != 0)
-               break;
+                       break;
+
 
                IFCQ_LOCK(ifq);
                if (!IFCQ_IS_READY(ifq)) {
@@ -1939,6 +1940,30 @@ if_delete_netagent(struct ifnet *ifp, uuid_t remove_agent_uuid)
        return (error);
 }
 
+boolean_t
+if_check_netagent(struct ifnet *ifp, uuid_t find_agent_uuid)
+{
+       boolean_t found = FALSE;
+
+       if (!ifp || uuid_is_null(find_agent_uuid))
+               return FALSE;
+
+       ifnet_lock_shared(ifp);
+
+       if (ifp->if_agentids != NULL) {
+               for (uint32_t index = 0; index < ifp->if_agentcount; index++) {
+                       if (uuid_compare(ifp->if_agentids[index], find_agent_uuid) == 0) {
+                               found = TRUE;
+                               break;
+                       }
+               }
+       }
+
+       ifnet_lock_done(ifp);
+
+       return found;
+}
+
 static __attribute__((noinline)) int
 ifioctl_netagent(struct ifnet *ifp, u_long cmd, caddr_t data, struct proc *p)
 {
@@ -2146,7 +2171,7 @@ ifioctl_iforder(u_long cmd, caddr_t data)
        case SIOCSIFORDER: {            /* struct if_order */
                struct if_order *ifo = (struct if_order *)(void *)data;
 
-               if (ifo->ifo_count == 0 || ifo->ifo_count > (u_int32_t)if_index) {
+               if (ifo->ifo_count > (u_int32_t)if_index) {
                        error = EINVAL;
                        break;
                }
@@ -2168,20 +2193,22 @@ ifioctl_iforder(u_long cmd, caddr_t data)
                        if (error != 0) {
                                break;
                        }
-               }
-               /* ordered_indices should not contain duplicates */
-               bool found_duplicate = FALSE;
-               for (uint32_t i = 0; i < (ifo->ifo_count - 1) && !found_duplicate ; i++){
-                       for (uint32_t j = i + 1; j < ifo->ifo_count && !found_duplicate ; j++){
-                               if (ordered_indices[j] == ordered_indices[i]){
-                                       error = EINVAL;
-                                       found_duplicate = TRUE;
-                                       break;
+
+                       /* ordered_indices should not contain duplicates */
+                       bool found_duplicate = FALSE;
+                       for (uint32_t i = 0; i < (ifo->ifo_count - 1) && !found_duplicate ; i++){
+                               for (uint32_t j = i + 1; j < ifo->ifo_count && !found_duplicate ; j++){
+                                       if (ordered_indices[j] == ordered_indices[i]){
+                                               error = EINVAL;
+                                               found_duplicate = TRUE;
+                                               break;
+                                       }
                                }
                        }
+                       if (found_duplicate) {
+                               break;
+                       }
                }
-               if (found_duplicate)
-                       break;
 
                error = ifnet_reset_order(ordered_indices, ifo->ifo_count);
 
@@ -2311,6 +2338,89 @@ ifioctl_nat64prefix(struct ifnet *ifp, u_long cmd, caddr_t data)
 #endif
 
 
+static int
+ifioctl_get_protolist(struct ifnet *ifp, u_int32_t * ret_count,
+    user_addr_t ifpl)
+{
+       u_int32_t       actual_count;
+       u_int32_t       count;
+       int             error = 0;
+       u_int32_t       *list = NULL;
+
+       /* find out how many */
+       count = if_get_protolist(ifp, NULL, 0);
+       if (ifpl == USER_ADDR_NULL) {
+               goto done;
+       }
+
+       /* copy out how many there's space for */
+       if (*ret_count < count) {
+               count = *ret_count;
+       }
+       if (count == 0) {
+               goto done;
+       }
+       list = _MALLOC(count * sizeof(*list), M_TEMP, M_WAITOK);
+       if (list == NULL) {
+               error = ENOMEM;
+               goto done;
+       }
+       actual_count = if_get_protolist(ifp, list, count);
+       if (actual_count < count) {
+               count = actual_count;
+       }
+       if (count != 0) {
+               error = copyout((caddr_t)list, ifpl, count * sizeof(*list));
+       }
+
+ done:
+       if (list != NULL) {
+               if_free_protolist(list);
+       }
+       *ret_count = count;
+       return (error);
+}
+
+static __attribute__((noinline)) int
+ifioctl_protolist(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+       int error = 0;
+
+       switch (cmd) {
+       case SIOCGIFPROTOLIST32: {              /* struct if_protolistreq32 */
+               struct if_protolistreq32        ifpl;
+
+               bcopy(data, &ifpl, sizeof(ifpl));
+               if (ifpl.ifpl_reserved != 0) {
+                       error = EINVAL;
+                       break;
+               }
+               error = ifioctl_get_protolist(ifp, &ifpl.ifpl_count,
+                   CAST_USER_ADDR_T(ifpl.ifpl_list));
+               bcopy(&ifpl, data, sizeof(ifpl));
+               break;
+       }
+       case SIOCGIFPROTOLIST64: {              /* struct if_protolistreq64 */
+               struct if_protolistreq64        ifpl;
+
+               bcopy(data, &ifpl, sizeof(ifpl));
+               if (ifpl.ifpl_reserved != 0) {
+                       error = EINVAL;
+                       break;
+               }
+               error = ifioctl_get_protolist(ifp, &ifpl.ifpl_count,
+                   ifpl.ifpl_list);
+               bcopy(&ifpl, data, sizeof(ifpl));
+               break;
+       }
+       default:
+               VERIFY(0);
+               /* NOTREACHED */
+       }
+
+       return (error);
+}
+
 /*
  * List the ioctl()s we can perform on restricted INTCOPROC interfaces.
  */
@@ -2382,6 +2492,8 @@ ifioctl_restrict_intcoproc(unsigned long cmd, const char *ifname,
        case SIOCGNBRINFO_IN6:
        case SIOCGIFALIFETIME_IN6:
        case SIOCGIFNETMASK_IN6:
+       case SIOCGIFPROTOLIST32:
+       case SIOCGIFPROTOLIST64:
                return (false);
        default:
 #if (DEBUG || DEVELOPMENT)
@@ -2629,6 +2741,12 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
                ifp = ifunit(ifname);
                break;
 
+       case SIOCGIFPROTOLIST32:                /* struct if_protolistreq32 */
+       case SIOCGIFPROTOLIST64:                /* struct if_protolistreq64 */
+               bcopy(((struct if_protolistreq *)(void *)data)->ifpl_name,
+                   ifname, IFNAMSIZ);
+               ifp = ifunit(ifname);
+               break;
        default:
                /*
                 * This is a bad assumption, but the code seems to
@@ -2718,6 +2836,12 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
                error = ifioctl_nat64prefix(ifp, cmd, data);
                break;
 #endif
+
+       case SIOCGIFPROTOLIST32:                /* struct if_protolistreq32 */
+       case SIOCGIFPROTOLIST64:                /* struct if_protolistreq64 */
+               error = ifioctl_protolist(ifp, cmd, data);
+               break;
+
        default:
                if (so->so_proto == NULL) {
                        error = EOPNOTSUPP;
@@ -2871,18 +2995,7 @@ ifioctl_ifreq(struct socket *so, u_long cmd, struct ifreq *ifr, struct proc *p)
                 * Send the event even upon error from the driver because
                 * we changed the flags.
                 */
-               ev_msg.vendor_code    = KEV_VENDOR_APPLE;
-               ev_msg.kev_class      = KEV_NETWORK_CLASS;
-               ev_msg.kev_subclass   = KEV_DL_SUBCLASS;
-
-               ev_msg.event_code = KEV_DL_SIFFLAGS;
-               strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
-               ev_data.if_family = ifp->if_family;
-               ev_data.if_unit   = (u_int32_t) ifp->if_unit;
-               ev_msg.dv[0].data_length = sizeof(struct net_event_data);
-               ev_msg.dv[0].data_ptr    = &ev_data;
-               ev_msg.dv[1].data_length = 0;
-               dlil_post_complete_msg(ifp, &ev_msg);
+               dlil_post_sifflags_msg(ifp);
 
                ifnet_touch_lastchange(ifp);
                break;
@@ -5021,17 +5134,13 @@ ifioctl_cassert(void)
        case SIOCSQOSMARKINGENABLED:
        case SIOCGQOSMARKINGMODE:
        case SIOCGQOSMARKINGENABLED:
+
+       case SIOCGIFPROTOLIST32:
+       case SIOCGIFPROTOLIST64:
                ;
        }
 }
 
-/*
- * XXX: This API is only used by BSD stack and for now will always return 0.
- * For Skywalk native drivers, preamble space need not be allocated in mbuf
- * as the preamble will be reserved in the translated skywalk packet
- * which is transmitted to the driver.
- * For Skywalk compat drivers currently headroom is always set to zero.
- */
 uint32_t
 ifnet_mbuf_packetpreamblelen(struct ifnet *ifp)
 {
index 2bb7c665585ecb8c403328f516282e1e3c45926d..2583ef5e72172b8054d2191d150328532a3a7763 100644 (file)
@@ -780,6 +780,7 @@ struct if_linkparamsreq {
        u_int32_t       iflpr_output_sched;
        u_int64_t       iflpr_output_tbr_rate;
        u_int32_t       iflpr_output_tbr_percent;
+       u_int64_t       iflpr_input_tbr_rate;
        struct if_bandwidths iflpr_output_bw;
        struct if_bandwidths iflpr_input_bw;
        struct if_latencies iflpr_output_lt;
@@ -882,17 +883,6 @@ struct if_agentidsreq {
        uuid_t          *ifar_uuids;            /* array of agent UUIDs */
 };
 
-/*
- * Structure for SIOCGIFNEXUS
- */
-struct if_nexusreq {
-       char            ifnr_name[IFNAMSIZ];    /* interface name */
-       uint64_t        ifnr_flags;             /* unused, must be zero */
-       uuid_t          ifnr_netif;             /* netif nexus instance UUID */
-       uuid_t          ifnr_multistack;        /* multistack nexus UUID */
-       uint64_t        ifnr_reserved[5];
-};
-
 #ifdef BSD_KERNEL_PRIVATE
 struct if_agentidsreq32 {
        char            ifar_name[IFNAMSIZ];
@@ -906,6 +896,17 @@ struct if_agentidsreq64 {
 };
 #endif /* BSD_KERNEL_PRIVATE */
 
+/*
+ * Structure for SIOCGIFNEXUS
+ */
+struct if_nexusreq {
+       char            ifnr_name[IFNAMSIZ];    /* interface name */
+       uint64_t        ifnr_flags;             /* unused, must be zero */
+       uuid_t          ifnr_netif;             /* netif nexus instance UUID */
+       uuid_t          ifnr_multistack;        /* multistack nexus UUID */
+       uint64_t        ifnr_reserved[5];
+};
+
 #define        DLIL_MODIDLEN   20      /* same as IFNET_MODIDLEN */
 #define        DLIL_MODARGLEN  12      /* same as IFNET_MODARGLEN */
 
@@ -1007,6 +1008,32 @@ struct if_tdmreq64 {
 };
 #endif
 
+/*
+ * Structure for SIOCGIFPROTOLIST.
+ */
+struct if_protolistreq {
+       char                    ifpl_name[IFNAMSIZ];
+       u_int32_t               ifpl_count;
+       u_int32_t               ifpl_reserved; /* must be zero */
+       u_int32_t               *ifpl_list;
+};
+
+#ifdef BSD_KERNEL_PRIVATE
+struct if_protolistreq32 {
+       char                    ifpl_name[IFNAMSIZ];
+       u_int32_t               ifpl_count;
+       u_int32_t               ifpl_reserved; /* must be zero */
+       user32_addr_t           ifpl_list;
+};
+
+struct if_protolistreq64 {
+       char                    ifpl_name[IFNAMSIZ];
+       u_int32_t               ifpl_count;
+       u_int32_t               ifpl_reserved; /* must be zero */
+       user64_addr_t           ifpl_list;
+};
+#endif /* BSD_KERNEL_PRIVATE */
+
 #endif /* PRIVATE */
 
 #ifdef KERNEL
index 3af936b87640e8674f7f408e3358876096c7ccb2..a4c7a69cb9f90031f628abc164a56482768178f5 100644 (file)
@@ -156,6 +156,18 @@ feth_is_detaching(if_fake_ref fakeif)
        return ((fakeif->iff_flags & IFF_FLAGS_DETACHING) != 0);
 }
 
+static int
+feth_enable_dequeue_stall(ifnet_t ifp, uint32_t enable)
+{
+       int error;
+
+       if (enable != 0)
+               error = ifnet_disable_output(ifp);
+       else
+               error = ifnet_enable_output(ifp);
+
+       return (error);
+}
 
 #define M_FAKE                 M_DEVBUF
 
@@ -713,14 +725,10 @@ feth_config(ifnet_t ifp, ifnet_t peer)
 
        /* generate link status event if we connect or disconnect */
        if (connected) {
-               ifnet_set_flags(ifp, IFF_RUNNING, IFF_RUNNING);
-               ifnet_set_flags(peer, IFF_RUNNING, IFF_RUNNING);
                interface_link_event(ifp, KEV_DL_LINK_ON);
                interface_link_event(peer, KEV_DL_LINK_ON);
        }
        else if (disconnected) {
-               ifnet_set_flags(ifp, 0, IFF_RUNNING);
-               ifnet_set_flags(peer, 0, IFF_RUNNING);
                interface_link_event(ifp, KEV_DL_LINK_OFF);
                interface_link_event(peer, KEV_DL_LINK_OFF);
        }
@@ -823,6 +831,14 @@ feth_set_drvspec(ifnet_t ifp, uint32_t cmd, u_int32_t len,
                }
                error = feth_set_media(ifp, &iffr);
                break;
+       case IF_FAKE_S_CMD_SET_DEQUEUE_STALL:
+               error = if_fake_request_copyin(user_addr, &iffr, len);
+               if (error != 0) {
+                       break;
+               }
+               error = feth_enable_dequeue_stall(ifp,
+                   iffr.iffr_dequeue_stall);
+               break;
        default:
                error = EOPNOTSUPP;
                break;
@@ -980,7 +996,17 @@ feth_ioctl(ifnet_t ifp, u_long cmd, void * data)
                break;
 
        case SIOCSIFFLAGS:
-               error = 0;
+               if ((ifp->if_flags & IFF_UP) != 0) {
+                       /* marked up, set running if not already set */
+                       if ((ifp->if_flags & IFF_RUNNING) == 0) {
+                               /* set running */
+                               error = ifnet_set_flags(ifp, IFF_RUNNING,
+                                   IFF_RUNNING);
+                       }
+               } else if ((ifp->if_flags & IFF_RUNNING) != 0) {
+                       /* marked down, clear running */
+                       error = ifnet_set_flags(ifp, 0, IFF_RUNNING);
+               }
                break;
 
        case SIOCADDMULTI:
index b6b14707051e7f259b8b08fb6736fbabf1e31ca7..1b8aaf4b169e3afe5e9a6bf31cee8cd8038a2309 100644 (file)
@@ -43,6 +43,7 @@ enum {
        IF_FAKE_S_CMD_NONE              = 0,
        IF_FAKE_S_CMD_SET_PEER          = 1,
        IF_FAKE_S_CMD_SET_MEDIA         = 2,
+       IF_FAKE_S_CMD_SET_DEQUEUE_STALL = 3,
 };
 
 /*
@@ -68,9 +69,15 @@ struct if_fake_request {
                char    iffru_buf[128];         /* stable size */
                struct if_fake_media    iffru_media;
                char    iffru_peer_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+               /*
+                * control dequeue stall. 0: disable dequeue stall, else
+                * enable dequeue stall.
+                */
+               uint32_t        iffru_dequeue_stall;
        } iffr_u;
 #define iffr_peer_name iffr_u.iffru_peer_name
 #define iffr_media     iffr_u.iffru_media
+#define iffr_dequeue_stall     iffr_u.iffru_dequeue_stall
 };
 
 #endif /* _NET_IF_FAKE_VAR_H_ */
index 9e2e6c6eaa28c22df8cdd2794420b76575b8b85d..bb9d156d07e0e21dff35ce0408f150c1bc5db278 100644 (file)
@@ -630,11 +630,13 @@ gif_input(
         * it occurs more times than we thought, we may change the policy
         * again.
         */
+    int32_t pktlen = m->m_pkthdr.len;
        if (proto_input(protocol_family, m) != 0) {
                ifnet_stat_increment_in(ifp, 0, 0, 1);
                m_freem(m);
-       } else
-               ifnet_stat_increment_in(ifp, 1, m->m_pkthdr.len, 0);
+    } else {
+               ifnet_stat_increment_in(ifp, 1, pktlen, 0);
+    }
 
        return (0);
 }
index 4c330d6396c00e9584b2f1b4e8f1dc128cc10291..7bf02edb9cd8d50a22736d6497ecc2633f334d10 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -58,7 +58,6 @@
 
 extern int net_qos_policy_restricted;
 extern int net_qos_policy_restrict_avapps;
-extern unsigned int if_enable_netagent;
 
 /* Kernel Control functions */
 static errno_t ipsec_ctl_bind(kern_ctl_ref kctlref, struct sockaddr_ctl *sac,
@@ -108,12 +107,13 @@ SYSCTL_NODE(_net, OID_AUTO, ipsec, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "IPsec");
 static int if_ipsec_verify_interface_creation = 0;
 SYSCTL_INT(_net_ipsec, OID_AUTO, verify_interface_creation, CTLFLAG_RW | CTLFLAG_LOCKED, &if_ipsec_verify_interface_creation, 0, "");
 
-#define IPSEC_IF_VERIFY(_e)            if (unlikely(if_ipsec_verify_interface_creation)) { VERIFY(_e); }
+#define IPSEC_IF_VERIFY(_e)            if (__improbable(if_ipsec_verify_interface_creation)) { VERIFY(_e); }
 
 #define IPSEC_IF_DEFAULT_SLOT_SIZE 2048
 #define IPSEC_IF_DEFAULT_RING_SIZE 64
 #define IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE 64
 #define IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE 128
+#define        IPSEC_IF_DEFAULT_BUF_SEG_SIZE   skmem_usr_buf_seg_size
 
 #define IPSEC_IF_MIN_RING_SIZE 16
 #define IPSEC_IF_MAX_RING_SIZE 1024
@@ -183,8 +183,10 @@ struct ipsec_pcb {
        uuid_t                          ipsec_kpipe_uuid;
        void *                          ipsec_kpipe_rxring;
        void *                          ipsec_kpipe_txring;
+       kern_pbufpool_t                 ipsec_kpipe_pp;
 
        kern_nexus_t            ipsec_netif_nexus;
+       kern_pbufpool_t                 ipsec_netif_pp;
        void *                          ipsec_netif_rxring;
        void *                          ipsec_netif_txring;
        uint64_t                        ipsec_netif_txring_size;
@@ -719,7 +721,7 @@ ipsec_kpipe_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                // Allocate rx packet
                kern_packet_t rx_ph = 0;
                error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-               if (unlikely(error != 0)) {
+               if (__improbable(error != 0)) {
                        printf("ipsec_kpipe_sync_rx %s: failed to allocate packet\n",
                                   pcb->ipsec_ifp->if_xname);
                        break;
@@ -732,6 +734,7 @@ ipsec_kpipe_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                tx_slot = kern_channel_get_next_slot(tx_ring, tx_slot, NULL);
 
                if (tx_ph == 0) {
+                       kern_pbufpool_free(rx_pp, rx_ph);
                        continue;
                }
                
@@ -1151,7 +1154,7 @@ ipsec_netif_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                // Allocate rx packet
                kern_packet_t rx_ph = 0;
                errno_t error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-               if (unlikely(error != 0)) {
+               if (__improbable(error != 0)) {
                        STATS_INC(nifs, NETIF_STATS_NOMEM_PKT);
                        STATS_INC(nifs, NETIF_STATS_DROPPED);
                        lck_mtx_unlock(&pcb->ipsec_input_chain_lock);
@@ -1370,7 +1373,7 @@ ipsec_netif_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                // Allocate rx packet
                kern_packet_t rx_ph = 0;
                error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-               if (unlikely(error != 0)) {
+               if (__improbable(error != 0)) {
                        STATS_INC(nifs, NETIF_STATS_NOMEM_PKT);
                        STATS_INC(nifs, NETIF_STATS_DROPPED);
                        break;
@@ -1383,6 +1386,7 @@ ipsec_netif_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                tx_slot = kern_channel_get_next_slot(tx_ring, tx_slot, NULL);
 
                if (tx_ph == 0) {
+                       kern_pbufpool_free(rx_pp, rx_ph);
                        continue;
                }
 
@@ -1570,10 +1574,11 @@ ipsec_nexus_ifattach(struct ipsec_pcb *pcb,
        errno_t err;
        nexus_controller_t controller = kern_nexus_shared_controller();
        struct kern_nexus_net_init net_init;
+       struct kern_pbufpool_init pp_init;
 
        nexus_name_t provider_name;
        snprintf((char *)provider_name, sizeof(provider_name),
-                        "com.apple.netif.ipsec%d", pcb->ipsec_unit);
+                        "com.apple.netif.%s", pcb->ipsec_if_xname);
 
        struct kern_nexus_provider_init prov_init = {
                .nxpi_version = KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION,
@@ -1613,6 +1618,21 @@ ipsec_nexus_ifattach(struct ipsec_pcb *pcb,
 
        pcb->ipsec_netif_txring_size = ring_size;
 
+       bzero(&pp_init, sizeof (pp_init));
+       pp_init.kbi_version = KERN_PBUFPOOL_CURRENT_VERSION;
+       pp_init.kbi_packets = pcb->ipsec_netif_ring_size * 2;
+       pp_init.kbi_bufsize = pcb->ipsec_slot_size;
+       pp_init.kbi_buf_seg_size = IPSEC_IF_DEFAULT_BUF_SEG_SIZE;
+       pp_init.kbi_max_frags = 1;
+       (void) snprintf((char *)pp_init.kbi_name, sizeof (pp_init.kbi_name),
+           "%s", provider_name);
+
+       err = kern_pbufpool_create(&pp_init, &pp_init, &pcb->ipsec_netif_pp, NULL);
+       if (err != 0) {
+               printf("%s pbufbool create failed, error %d\n", __func__, err);
+               goto failed;
+       }
+
        err = kern_nexus_controller_register_provider(controller,
                                                                                                  ipsec_nx_dom_prov,
                                                                                                  provider_name,
@@ -1633,6 +1653,7 @@ ipsec_nexus_ifattach(struct ipsec_pcb *pcb,
        net_init.nxneti_eparams = init_params;
        net_init.nxneti_lladdr = NULL;
        net_init.nxneti_prepare = ipsec_netif_prepare;
+       net_init.nxneti_tx_pbufpool = pcb->ipsec_netif_pp;
        err = kern_nexus_controller_alloc_net_provider_instance(controller,
                                                                                                                        pcb->ipsec_nx.if_provider,
                                                                                                                        pcb,
@@ -1653,6 +1674,10 @@ failed:
        if (nxa) {
                kern_nexus_attr_destroy(nxa);
        }
+       if (err && pcb->ipsec_netif_pp != NULL) {
+               kern_pbufpool_destroy(pcb->ipsec_netif_pp);
+               pcb->ipsec_netif_pp = NULL;
+       }
        return (err);
 }
 
@@ -1683,8 +1708,9 @@ ipsec_detach_provider_and_instance(uuid_t provider, uuid_t instance)
 }
 
 static void
-ipsec_nexus_detach(ipsec_nx_t nx)
+ipsec_nexus_detach(struct ipsec_pcb *pcb)
 {
+       ipsec_nx_t nx = &pcb->ipsec_nx;
        nexus_controller_t controller = kern_nexus_shared_controller();
        errno_t err;
 
@@ -1713,6 +1739,11 @@ ipsec_nexus_detach(ipsec_nx_t nx)
        ipsec_detach_provider_and_instance(nx->ms_provider,
                                                                           nx->ms_instance);
 
+       if (pcb->ipsec_netif_pp != NULL) {
+               kern_pbufpool_destroy(pcb->ipsec_netif_pp);
+               pcb->ipsec_netif_pp = NULL;
+
+       }
        memset(nx, 0, sizeof(*nx));
 }
 
@@ -1858,7 +1889,7 @@ ipsec_multistack_attach(struct ipsec_pcb *pcb)
        return (0);
 
 failed:
-       ipsec_nexus_detach(nx);
+       ipsec_nexus_detach(pcb);
 
        errno_t detach_error = 0;
        if ((detach_error = ifnet_detach(pcb->ipsec_ifp)) != 0) {
@@ -2006,6 +2037,10 @@ ipsec_disable_channel(struct ipsec_pcb *pcb)
        }
 
        if (!result) {
+               if (pcb->ipsec_kpipe_pp != NULL) {
+                       kern_pbufpool_destroy(pcb->ipsec_kpipe_pp);
+                       pcb->ipsec_kpipe_pp = NULL;
+               }
                ipsec_unregister_kernel_pipe_nexus();
        }
 
@@ -2016,6 +2051,7 @@ static errno_t
 ipsec_enable_channel(struct ipsec_pcb *pcb, struct proc *proc)
 {
        struct kern_nexus_init init;
+       struct kern_pbufpool_init pp_init;
        errno_t result;
 
        result = ipsec_register_kernel_pipe_nexus();
@@ -2027,14 +2063,38 @@ ipsec_enable_channel(struct ipsec_pcb *pcb, struct proc *proc)
 
        lck_rw_lock_exclusive(&pcb->ipsec_pcb_lock);
 
+       /* ipsec driver doesn't support channels without a netif */
+       if (!pcb->ipsec_use_netif) {
+               result = EOPNOTSUPP;
+               goto done;
+       }
+
        if (pcb->ipsec_kpipe_enabled) {
                result = EEXIST; // return success instead?
                goto done;
        }
 
+       bzero(&pp_init, sizeof (pp_init));
+       pp_init.kbi_version = KERN_PBUFPOOL_CURRENT_VERSION;
+       pp_init.kbi_packets = pcb->ipsec_netif_ring_size * 2;
+       pp_init.kbi_bufsize = pcb->ipsec_slot_size;
+       pp_init.kbi_buf_seg_size = IPSEC_IF_DEFAULT_BUF_SEG_SIZE;
+       pp_init.kbi_max_frags = 1;
+       pp_init.kbi_flags |= KBIF_QUANTUM;
+       (void) snprintf((char *)pp_init.kbi_name, sizeof (pp_init.kbi_name),
+           "com.apple.kpipe.%s", pcb->ipsec_if_xname);
+
+       result = kern_pbufpool_create(&pp_init, &pp_init, &pcb->ipsec_kpipe_pp,
+           NULL);
+       if (result != 0) {
+               printf("%s pbufbool create failed, error %d\n", __func__, result);
+               goto done;
+       }
+
        VERIFY(uuid_is_null(pcb->ipsec_kpipe_uuid));
        bzero(&init, sizeof (init));
        init.nxi_version = KERN_NEXUS_CURRENT_VERSION;
+       init.nxi_tx_pbufpool = pcb->ipsec_kpipe_pp;
        result = kern_nexus_controller_alloc_provider_instance(ipsec_ncd,
                                                                                                                   ipsec_kpipe_uuid, pcb, &pcb->ipsec_kpipe_uuid, &init);
        if (result) {
@@ -2058,6 +2118,10 @@ done:
        lck_rw_unlock_exclusive(&pcb->ipsec_pcb_lock);
        
        if (result) {
+               if (pcb->ipsec_kpipe_pp != NULL) {
+                       kern_pbufpool_destroy(pcb->ipsec_kpipe_pp);
+                       pcb->ipsec_kpipe_pp = NULL;
+               }
                ipsec_unregister_kernel_pipe_nexus();
        }
        
@@ -2460,10 +2524,14 @@ ipsec_ctl_disconnect(__unused kern_ctl_ref      kctlref,
 
                        if (!uuid_is_null(kpipe_uuid)) {
                                if (kern_nexus_controller_free_provider_instance(ipsec_ncd, kpipe_uuid) == 0) {
+                                       if (pcb->ipsec_kpipe_pp != NULL) {
+                                               kern_pbufpool_destroy(pcb->ipsec_kpipe_pp);
+                                               pcb->ipsec_kpipe_pp = NULL;
+                                       }
                                        ipsec_unregister_kernel_pipe_nexus();
                                }
                        }
-                       ipsec_nexus_detach(&pcb->ipsec_nx);
+                       ipsec_nexus_detach(pcb);
 
                        /* Decrement refcnt to finish detaching and freeing */
                        ifnet_decr_iorefcnt(ifp);
@@ -2475,6 +2543,10 @@ ipsec_ctl_disconnect(__unused kern_ctl_ref       kctlref,
 #if IPSEC_NEXUS
                        if (!uuid_is_null(kpipe_uuid)) {
                                if (kern_nexus_controller_free_provider_instance(ipsec_ncd, kpipe_uuid) == 0) {
+                                       if (pcb->ipsec_kpipe_pp != NULL) {
+                                               kern_pbufpool_destroy(pcb->ipsec_kpipe_pp);
+                                               pcb->ipsec_kpipe_pp = NULL;
+                                       }
                                        ipsec_unregister_kernel_pipe_nexus();
                                }
                        }
@@ -2673,18 +2745,19 @@ ipsec_ctl_setopt(__unused kern_ctl_ref  kctlref,
                                result = EINVAL;
                                break;
                        }
-                       if (!if_enable_netagent) {
+                       if (!if_is_netagent_enabled()) {
                                result = ENOTSUP;
                                break;
                        }
+                       if (uuid_is_null(pcb->ipsec_nx.ms_agent)) {
+                               result = ENOENT;
+                               break;
+                       }
+
                        if (*(int *)data) {
-                               if (!uuid_is_null(pcb->ipsec_nx.ms_agent)) {
                                        if_add_netagent(pcb->ipsec_ifp, pcb->ipsec_nx.ms_agent);
-                               }
                        } else {
-                               if (!uuid_is_null(pcb->ipsec_nx.ms_agent)) {
                                        if_delete_netagent(pcb->ipsec_ifp, pcb->ipsec_nx.ms_agent);
-                               }
                        }
                        break;
                }
@@ -2715,7 +2788,9 @@ ipsec_ctl_setopt(__unused kern_ctl_ref    kctlref,
                                result = EINVAL;
                                break;
                        }
-                       pcb->ipsec_use_netif = true;
+                       lck_rw_lock_exclusive(&pcb->ipsec_pcb_lock);
+                       pcb->ipsec_use_netif = !!(*(int *)data);
+                       lck_rw_unlock_exclusive(&pcb->ipsec_pcb_lock);
                        break;
                }
                case IPSEC_OPT_SLOT_SIZE: {
@@ -2855,6 +2930,38 @@ ipsec_ctl_getopt(__unused kern_ctl_ref kctlref,
                }
 
 #if IPSEC_NEXUS
+
+               case IPSEC_OPT_ENABLE_CHANNEL: {
+                       if (*len != sizeof(int)) {
+                               result = EMSGSIZE;
+                       } else {
+                               lck_rw_lock_shared(&pcb->ipsec_pcb_lock);
+                               *(int *)data = pcb->ipsec_kpipe_enabled;
+                               lck_rw_unlock_shared(&pcb->ipsec_pcb_lock);
+                       }
+                       break;
+               }
+
+               case IPSEC_OPT_ENABLE_FLOWSWITCH: {
+                       if (*len != sizeof(int)) {
+                               result = EMSGSIZE;
+                       } else {
+                               *(int *)data = if_check_netagent(pcb->ipsec_ifp, pcb->ipsec_nx.ms_agent);
+                       }
+                       break;
+               }
+
+               case IPSEC_OPT_ENABLE_NETIF: {
+                       if (*len != sizeof(int)) {
+                               result = EMSGSIZE;
+                       } else {
+                               lck_rw_lock_shared(&pcb->ipsec_pcb_lock);
+                               *(int *)data = !!pcb->ipsec_use_netif;
+                               lck_rw_unlock_shared(&pcb->ipsec_pcb_lock);
+                       }
+                       break;
+               }
+
                case IPSEC_OPT_GET_CHANNEL_UUID: {
                        lck_rw_lock_shared(&pcb->ipsec_pcb_lock);
                        if (uuid_is_null(pcb->ipsec_kpipe_uuid)) {
@@ -3190,12 +3297,12 @@ ipsec_ioctl(ifnet_t interface,
                        u_long command,
                        void *data)
 {
-       struct ipsec_pcb *pcb = ifnet_softc(interface);
        errno_t result = 0;
        
        switch(command) {
                case SIOCSIFMTU: {
 #if IPSEC_NEXUS
+                       struct ipsec_pcb *pcb = ifnet_softc(interface);
                        if (pcb->ipsec_use_netif) {
                                // Make sure we can fit packets in the channel buffers
                                if (((uint64_t)((struct ifreq*)data)->ifr_mtu) > pcb->ipsec_slot_size) {
@@ -3253,14 +3360,15 @@ ipsec_proto_input(ifnet_t interface,
                        af = AF_INET6;
                }
                bpf_tap_in(interface, DLT_NULL, m, &af, sizeof(af));
+               pktap_input(interface, protocol, m, NULL);
        }
-       pktap_input(interface, protocol, m, NULL);
 
+    int32_t pktlen = m->m_pkthdr.len;
        if (proto_input(protocol, m) != 0) {
                ifnet_stat_increment_in(interface, 0, 0, 1);
                m_freem(m);
        } else {
-               ifnet_stat_increment_in(interface, 1, m->m_pkthdr.len, 0);
+               ifnet_stat_increment_in(interface, 1, pktlen, 0);
        }
        
        return 0;
@@ -3304,9 +3412,9 @@ errno_t
 ipsec_inject_inbound_packet(ifnet_t    interface,
                                                        mbuf_t packet)
 {
+#if IPSEC_NEXUS
        struct ipsec_pcb *pcb = ifnet_softc(interface);
 
-#if IPSEC_NEXUS
        if (pcb->ipsec_use_netif) {
                lck_rw_lock_shared(&pcb->ipsec_pcb_lock);
 
diff --git a/bsd/net/if_ports_used.c b/bsd/net/if_ports_used.c
new file mode 100644 (file)
index 0000000..f5f7f9c
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2017-2018 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/mcache.h>
+#include <sys/malloc.h>
+#include <sys/kauth.h>
+#include <sys/bitstring.h>
+#include <sys/priv.h>
+#include <sys/socket.h>
+
+#include <kern/locks.h>
+#include <kern/zalloc.h>
+
+#include <libkern/libkern.h>
+#include <mach/branch_predicates.h>
+
+#include <net/kpi_interface.h>
+#include <net/if_var.h>
+#include <net/if_ports_used.h>
+
+#include <netinet/in_pcb.h>
+
+
+#include <stdbool.h>
+
+#include <os/log.h>
+
+extern bool IOPMCopySleepWakeUUIDKey(char *buffer, size_t buf_len);
+
+SYSCTL_DECL(_net_link_generic_system);
+
+SYSCTL_NODE(_net_link_generic_system, OID_AUTO, port_used,
+    CTLFLAG_RW | CTLFLAG_LOCKED, 0, "if port used");
+
+static uuid_t          current_wakeuuid;
+SYSCTL_OPAQUE(_net_link_generic_system_port_used, OID_AUTO, current_wakeuuid,
+    CTLFLAG_RD|CTLFLAG_LOCKED,
+    current_wakeuuid, sizeof(uuid_t), "S,uuid_t", "");
+
+static int sysctl_net_port_info_list SYSCTL_HANDLER_ARGS;
+SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO, list,
+    CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
+    sysctl_net_port_info_list, "S,xnpigen", "");
+
+static int use_test_wakeuuid = 0;
+static uuid_t test_wakeuuid;
+
+#if (DEVELOPMENT || DEBUG)
+SYSCTL_INT(_net_link_generic_system_port_used, OID_AUTO, use_test_wakeuuid,
+    CTLFLAG_RW | CTLFLAG_LOCKED,
+    &use_test_wakeuuid, 0, "");
+
+int sysctl_new_test_wakeuuid SYSCTL_HANDLER_ARGS;
+SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO, new_test_wakeuuid,
+    CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0,
+    sysctl_new_test_wakeuuid, "S,uuid_t", "");
+
+int sysctl_clear_test_wakeuuid SYSCTL_HANDLER_ARGS;
+SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO, clear_test_wakeuuid,
+    CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0,
+    sysctl_clear_test_wakeuuid, "S,uuid_t", "");
+
+SYSCTL_OPAQUE(_net_link_generic_system_port_used, OID_AUTO, test_wakeuuid,
+    CTLFLAG_RD|CTLFLAG_LOCKED,
+    test_wakeuuid, sizeof(uuid_t), "S,uuid_t", "");
+#endif /* (DEVELOPMENT || DEBUG) */
+
+static int sysctl_get_ports_used SYSCTL_HANDLER_ARGS;
+SYSCTL_NODE(_net_link_generic_system, OID_AUTO, get_ports_used,
+    CTLFLAG_RD | CTLFLAG_LOCKED,
+    sysctl_get_ports_used, "");
+
+static uint32_t net_port_entry_count = 0;
+SYSCTL_UINT(_net_link_generic_system_port_used, OID_AUTO, entry_count,
+    CTLFLAG_RW | CTLFLAG_LOCKED,
+    &net_port_entry_count, 0, "");
+
+static uint32_t net_port_entry_gen = 0;
+SYSCTL_UINT(_net_link_generic_system_port_used, OID_AUTO, entry_gen,
+    CTLFLAG_RW | CTLFLAG_LOCKED,
+    &net_port_entry_gen, 0, "");
+
+static int if_ports_used_verbose = 0;
+SYSCTL_INT(_net_link_generic_system_port_used, OID_AUTO, verbose,
+    CTLFLAG_RW | CTLFLAG_LOCKED,
+    &if_ports_used_verbose, 0, "");
+
+static unsigned long wakeuuid_not_set_count = 0;
+SYSCTL_ULONG(_net_link_generic_system_port_used, OID_AUTO,
+    wakeuuid_not_set_count, CTLFLAG_RD | CTLFLAG_LOCKED,
+    &wakeuuid_not_set_count, 0);
+
+struct timeval wakeuuid_not_set_last_time;
+int sysctl_wakeuuid_not_set_last_time SYSCTL_HANDLER_ARGS;
+static SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO,
+    wakeuuid_not_set_last_time, CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
+    0, 0, sysctl_wakeuuid_not_set_last_time, "S,timeval", "");
+
+char wakeuuid_not_set_last_if [IFXNAMSIZ];
+int sysctl_wakeuuid_not_set_last_if SYSCTL_HANDLER_ARGS;
+static SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO,
+    wakeuuid_not_set_last_if, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
+    0, 0, sysctl_wakeuuid_not_set_last_if, "A", "");
+
+
+static int if_ports_used_inited = 0;
+
+decl_lck_mtx_data(static, net_port_entry_head_lock);
+static lck_grp_t *net_port_entry_head_lock_group;
+
+struct net_port_entry {
+       SLIST_ENTRY(net_port_entry)     npe_next;
+       struct net_port_info            npe_npi;
+};
+
+static struct zone *net_port_entry_zone = NULL;
+
+#define        NET_PORT_ENTRY_ZONE_MAX 128
+#define        NET_PORT_ENTRY_ZONE_NAME "net_port_entry"
+
+static SLIST_HEAD(net_port_entry_list, net_port_entry) net_port_entry_list =
+    SLIST_HEAD_INITIALIZER(&net_port_entry_list);
+
+struct timeval wakeuiid_last_check;
+
+void
+if_ports_used_init(void)
+{
+       if (if_ports_used_inited == 0) {
+               lck_grp_attr_t *lck_grp_attributes = NULL;
+               lck_attr_t *lck_attributes = NULL;
+
+               timerclear(&wakeuiid_last_check);
+               uuid_clear(current_wakeuuid);
+               uuid_clear(test_wakeuuid);
+
+               lck_grp_attributes = lck_grp_attr_alloc_init();
+               net_port_entry_head_lock_group = lck_grp_alloc_init(
+                   "net port entry lock", lck_grp_attributes);
+
+               lck_attributes = lck_attr_alloc_init();
+               if (lck_attributes == NULL) {
+                       panic("%s: lck_attr_alloc_init() failed", __func__);
+               }
+               lck_mtx_init(&net_port_entry_head_lock,
+                   net_port_entry_head_lock_group,
+                   lck_attributes);
+
+               net_port_entry_count = 0;
+               net_port_entry_zone = zinit(sizeof(struct net_port_entry),
+                   NET_PORT_ENTRY_ZONE_MAX * sizeof(struct net_port_entry),
+                   0, NET_PORT_ENTRY_ZONE_NAME);
+               if (net_port_entry_zone == NULL) {
+                       panic("%s: zinit(%s) failed", __func__,
+                           NET_PORT_ENTRY_ZONE_NAME);
+               }
+               zone_change(net_port_entry_zone, Z_EXPAND, TRUE);
+               zone_change(net_port_entry_zone, Z_CALLERACCT, FALSE);
+
+               if_ports_used_inited = 1;
+
+               lck_attr_free(lck_attributes);
+               lck_grp_attr_free(lck_grp_attributes);
+       }
+}
+
+static void
+net_port_entry_list_clear(void)
+{
+       struct net_port_entry *npe;
+
+       LCK_MTX_ASSERT(&net_port_entry_head_lock, LCK_MTX_ASSERT_OWNED);
+
+       while ((npe = SLIST_FIRST(&net_port_entry_list)) != NULL) {
+               SLIST_REMOVE_HEAD(&net_port_entry_list, npe_next);
+
+               zfree(net_port_entry_zone, npe);
+       }
+       net_port_entry_count = 0;
+       net_port_entry_gen++;
+}
+
+static bool
+get_test_wake_uuid(uuid_t wakeuuid)
+{
+       if (__improbable(use_test_wakeuuid)) {
+               if (!uuid_is_null(test_wakeuuid)) {
+                       if (wakeuuid != NULL) {
+                               uuid_copy(wakeuuid, test_wakeuuid);
+                       }
+                       return (true);
+               } else {
+                       return (false);
+               }
+       } else {
+               return (false);
+       }
+}
+
+static bool
+is_wakeuuid_set(void)
+{
+       /*
+        * IOPMCopySleepWakeUUIDKey() tells if SleepWakeUUID is currently set
+        * That means we are currently in a sleep/wake cycle
+        */
+       return (get_test_wake_uuid(NULL) || IOPMCopySleepWakeUUIDKey(NULL, 0));
+}
+
+void
+if_ports_used_update_wakeuuid(struct ifnet *ifp)
+{
+       uuid_t wakeuuid;
+       bool wakeuuid_is_set = false;
+       bool updated = false;
+
+       if (__improbable(use_test_wakeuuid)) {
+               wakeuuid_is_set = get_test_wake_uuid(wakeuuid);
+       } else {
+               uuid_string_t wakeuuid_str;
+
+               wakeuuid_is_set = IOPMCopySleepWakeUUIDKey(wakeuuid_str,
+                   sizeof(wakeuuid_str));
+               if (wakeuuid_is_set) {
+                       uuid_parse(wakeuuid_str, wakeuuid);
+               }
+       }
+
+       if (!wakeuuid_is_set) {
+               if (if_ports_used_verbose > 0) {
+                       os_log_info(OS_LOG_DEFAULT,
+                           "%s: SleepWakeUUID not set, "
+                           "don't update the port list for %s\n",
+                           __func__, ifp != NULL ? if_name(ifp) : "");
+               }
+               wakeuuid_not_set_count += 1;
+               if (ifp != NULL) {
+                       microtime(&wakeuuid_not_set_last_time);
+                       strlcpy(wakeuuid_not_set_last_if, if_name(ifp),
+                           sizeof(wakeuuid_not_set_last_if));
+               }       
+               return;
+       }
+
+       lck_mtx_lock(&net_port_entry_head_lock);
+       if (uuid_compare(wakeuuid, current_wakeuuid) != 0) {
+               net_port_entry_list_clear();
+               uuid_copy(current_wakeuuid, wakeuuid);
+               updated = true;
+       }
+       /* 
+        * Record the time last checked
+        */
+       microuptime(&wakeuiid_last_check);
+       lck_mtx_unlock(&net_port_entry_head_lock);
+
+       if (updated && if_ports_used_verbose > 0) {
+               uuid_string_t uuid_str;
+
+               uuid_unparse(current_wakeuuid, uuid_str);
+               log(LOG_ERR, "%s: current wakeuuid %s\n",
+                   __func__,
+                   uuid_str);
+       }
+}
+
+static bool
+net_port_info_equal(const struct net_port_info *x,
+    const struct net_port_info *y)
+{
+       ASSERT(x != NULL && y != NULL);
+
+       if (x->npi_if_index == y->npi_if_index &&
+           x->npi_local_port == y->npi_local_port &&
+           x->npi_foreign_port == y->npi_foreign_port &&
+           x->npi_owner_pid == y->npi_owner_pid &&
+           x->npi_effective_pid == y->npi_effective_pid &&
+           x->npi_flags == y->npi_flags &&
+           memcmp(&x->npi_local_addr_, &y->npi_local_addr_,
+               sizeof(union in_addr_4_6)) == 0 &&
+           memcmp(&x->npi_foreign_addr_, &y->npi_foreign_addr_,
+               sizeof(union in_addr_4_6)) == 0) {
+               return (true);
+       }
+       return (false);
+}
+
+static bool
+net_port_info_has_entry(const struct net_port_info *npi)
+{
+       struct net_port_entry *npe;
+
+       LCK_MTX_ASSERT(&net_port_entry_head_lock, LCK_MTX_ASSERT_OWNED);
+
+       SLIST_FOREACH(npe, &net_port_entry_list, npe_next) {
+               if (net_port_info_equal(&npe->npe_npi, npi)) {
+                       return (true);
+               }
+       }
+
+       return (false);
+}
+
+static bool
+net_port_info_add_entry(const struct net_port_info *npi)
+{
+       struct net_port_entry   *npe = NULL;
+       uint32_t num = 0;
+       bool entry_added = false;
+
+       ASSERT(npi != NULL);
+
+       if (__improbable(is_wakeuuid_set() == false)) {
+               if (if_ports_used_verbose > 0) {
+                       log(LOG_ERR, "%s: wakeuuid not set %u not adding "
+                           "port: %u flags: 0x%xif: %u pid: %u epid %u\n",
+                           __func__,
+                           ntohs(npi->npi_local_port),
+                           npi->npi_flags,
+                           npi->npi_if_index,
+                           npi->npi_owner_pid,
+                           npi->npi_effective_pid);
+               }
+               return (0);
+       }
+
+       npe = zalloc(net_port_entry_zone);
+       if (__improbable(npe == NULL)) {
+               log(LOG_ERR, "%s: zalloc() failed for "
+                   "port: %u flags: 0x%x if: %u pid: %u epid %u\n",
+                   __func__,
+                   ntohs(npi->npi_local_port),
+                   npi->npi_flags,
+                   npi->npi_if_index,
+                   npi->npi_owner_pid,
+                   npi->npi_effective_pid);
+               return (0);
+       }
+       bzero(npe, sizeof(struct net_port_entry));
+
+       memcpy(&npe->npe_npi, npi, sizeof(npe->npe_npi));
+
+       lck_mtx_lock(&net_port_entry_head_lock);
+
+       if (net_port_info_has_entry(npi) == false) {
+               SLIST_INSERT_HEAD(&net_port_entry_list, npe, npe_next);
+               num = net_port_entry_count++;
+               entry_added = true;
+
+               if (if_ports_used_verbose > 0) {
+                       log(LOG_ERR, "%s: num %u for "
+                           "port: %u flags: 0x%x if: %u pid: %u epid %u\n",
+                           __func__,
+                           num,
+                           ntohs(npi->npi_local_port),
+                           npi->npi_flags,
+                           npi->npi_if_index,
+                           npi->npi_owner_pid,
+                           npi->npi_effective_pid);
+               }
+       } else {
+               if (if_ports_used_verbose > 0) {
+                       log(LOG_ERR, "%s: entry already added "
+                           "port: %u flags: 0x%x if: %u pid: %u epid %u\n",
+                           __func__,
+                           ntohs(npi->npi_local_port),
+                           npi->npi_flags,
+                           npi->npi_if_index,
+                           npi->npi_owner_pid,
+                           npi->npi_effective_pid);
+               }
+       }
+
+       lck_mtx_unlock(&net_port_entry_head_lock);
+
+       if (entry_added == false) {
+               zfree(net_port_entry_zone, npe);
+               npe = NULL;
+       }
+       return (entry_added);
+}
+
+#if (DEVELOPMENT || DEBUG)
+int
+sysctl_new_test_wakeuuid SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+       int error = 0;
+
+       if (kauth_cred_issuser(kauth_cred_get()) == 0) {
+               return (EPERM);
+       }
+       if (req->oldptr == USER_ADDR_NULL) {
+               req->oldidx = sizeof(uuid_t);
+               return (0);
+       }
+       if (req->newptr != USER_ADDR_NULL) {
+               uuid_generate(test_wakeuuid);
+       }
+       error = SYSCTL_OUT(req, test_wakeuuid,
+           MIN(sizeof(uuid_t), req->oldlen));
+
+       return (error);
+}
+
+int
+sysctl_clear_test_wakeuuid SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+       int error = 0;
+
+       if (kauth_cred_issuser(kauth_cred_get()) == 0) {
+               return (EPERM);
+       }
+       if (req->oldptr == USER_ADDR_NULL) {
+               req->oldidx = sizeof(uuid_t);
+               return (0);
+       }
+       if (req->newptr != USER_ADDR_NULL) {
+               uuid_clear(test_wakeuuid);
+       }
+       error = SYSCTL_OUT(req, test_wakeuuid,
+           MIN(sizeof(uuid_t), req->oldlen));
+
+       return (error);
+}
+
+#endif /* (DEVELOPMENT || DEBUG) */
+
+int
+sysctl_wakeuuid_not_set_last_time SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+
+       if (proc_is64bit(req->p)) {
+               struct user64_timeval tv;
+
+               tv.tv_sec = wakeuuid_not_set_last_time.tv_sec;
+               tv.tv_usec = wakeuuid_not_set_last_time.tv_usec;
+               return SYSCTL_OUT(req, &tv, sizeof(tv));
+       } else {
+               struct user32_timeval tv;
+
+               tv.tv_sec = wakeuuid_not_set_last_time.tv_sec;
+               tv.tv_usec = wakeuuid_not_set_last_time.tv_usec;
+               return SYSCTL_OUT(req, &tv, sizeof(tv));
+       }
+}
+
+int
+sysctl_wakeuuid_not_set_last_if SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+
+       return SYSCTL_OUT(req, &wakeuuid_not_set_last_if,
+           strlen(wakeuuid_not_set_last_if) + 1);
+}
+
+static int
+sysctl_net_port_info_list SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+       int error = 0;
+       struct xnpigen xnpigen;
+       struct net_port_entry *npe;
+
+       if ((error = priv_check_cred(kauth_cred_get(),
+           PRIV_NET_PRIVILEGED_NETWORK_STATISTICS, 0)) != 0) {
+               return (EPERM);
+       }
+       lck_mtx_lock(&net_port_entry_head_lock);
+
+       if (req->oldptr == USER_ADDR_NULL) {
+               /* Add a 25 % cushion */
+               uint32_t cnt = net_port_entry_count;
+               cnt += cnt >> 4;
+               req->oldidx = sizeof(struct xnpigen) +
+                       cnt * sizeof(struct net_port_info);
+               goto done;
+       }
+
+       memset(&xnpigen, 0, sizeof(struct xnpigen));
+       xnpigen.xng_len = sizeof(struct xnpigen);
+       xnpigen.xng_gen = net_port_entry_gen;
+       uuid_copy(xnpigen.xng_wakeuuid, current_wakeuuid);
+       xnpigen.xng_npi_count = net_port_entry_count;
+       xnpigen.xng_npi_size = sizeof(struct net_port_info);
+       error = SYSCTL_OUT(req, &xnpigen, sizeof (xnpigen));
+       if (error != 0) {
+               printf("%s: SYSCTL_OUT(xnpigen) error %d\n",
+                   __func__, error);
+               goto done;
+       }
+
+       SLIST_FOREACH(npe, &net_port_entry_list, npe_next) {
+               error = SYSCTL_OUT(req, &npe->npe_npi,
+                   sizeof(struct net_port_info));
+               if (error != 0) {
+                       printf("%s: SYSCTL_OUT(npi) error %d\n",
+                           __func__, error);
+                       goto done;
+               }
+       }
+done:
+       lck_mtx_unlock(&net_port_entry_head_lock);
+
+       return (error);
+}
+
+/*
+ * Mirror the arguments of ifnet_get_local_ports_extended()
+ *  ifindex
+ *  protocol
+ *  flags
+ */
+static int
+sysctl_get_ports_used SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp)
+       int *name = (int *)arg1;
+       int namelen = arg2;
+       int error = 0;
+       int idx;
+       protocol_family_t protocol;
+       u_int32_t flags;
+       ifnet_t ifp = NULL;
+       u_int8_t *bitfield = NULL;
+
+       if (req->newptr != USER_ADDR_NULL) {
+               error = EPERM;
+               goto done;
+       }
+       /*
+        * 3 is the required number of parameters: ifindex, protocol and flags
+        */
+       if (namelen != 3) {
+               error = ENOENT;
+               goto done;
+       }
+
+       if (req->oldptr == USER_ADDR_NULL) {
+               req->oldidx = bitstr_size(IP_PORTRANGE_SIZE);
+               goto done;
+       }
+       if (req->oldlen < bitstr_size(IP_PORTRANGE_SIZE)) {
+               error = ENOMEM;
+               goto done;
+       }
+
+       idx = name[0];
+       protocol = name[1];
+       flags = name[2];
+
+       ifnet_head_lock_shared();
+       if (!IF_INDEX_IN_RANGE(idx)) {
+               ifnet_head_done();
+               error = ENOENT;
+               goto done;
+       }
+       ifp = ifindex2ifnet[idx];
+       ifnet_head_done();
+
+       bitfield = _MALLOC(bitstr_size(IP_PORTRANGE_SIZE), M_TEMP,
+           M_WAITOK | M_ZERO);
+       if (bitfield == NULL) {
+               error = ENOMEM;
+               goto done;
+       }
+       error = ifnet_get_local_ports_extended(ifp, protocol, flags, bitfield);
+       if (error != 0) {
+               printf("%s: ifnet_get_local_ports_extended() error %d\n",
+                   __func__, error);
+               goto done;
+       }
+       error = SYSCTL_OUT(req, bitfield, bitstr_size(IP_PORTRANGE_SIZE));
+done:
+       if (bitfield != NULL)
+               _FREE(bitfield, M_TEMP);
+       return (error);
+}
+
+__private_extern__ void
+if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp)
+{
+       struct net_port_info npi;
+       struct socket *so = inp->inp_socket;
+
+       bzero(&npi, sizeof(struct net_port_info));
+
+       npi.npi_if_index = ifindex;
+
+       npi.npi_flags |= NPIF_SOCKET;
+
+       npi.npi_timestamp.tv_sec = wakeuiid_last_check.tv_sec;
+       npi.npi_timestamp.tv_usec = wakeuiid_last_check.tv_usec;
+
+       if (SOCK_PROTO(so) == IPPROTO_TCP) {
+               npi.npi_flags |= NPIF_TCP;
+       } else if (SOCK_PROTO(so) == IPPROTO_UDP) {
+               npi.npi_flags |= NPIF_UDP;
+       } else {
+               panic("%s: unexpected protocol %u for inp %p\n", __func__,
+                   SOCK_PROTO(inp->inp_socket), inp);
+       }
+
+       uuid_copy(npi.npi_flow_uuid, inp->necp_client_uuid);
+
+       npi.npi_local_port = inp->inp_lport;
+       npi.npi_foreign_port = inp->inp_fport;
+
+       if (inp->inp_vflag & INP_IPV4) {
+               npi.npi_flags |= NPIF_IPV4;
+               npi.npi_local_addr_in = inp->inp_laddr;
+               npi.npi_foreign_addr_in = inp->inp_faddr;
+       } else {
+               npi.npi_flags |= NPIF_IPV6;
+               memcpy(&npi.npi_local_addr_in6,
+                   &inp->in6p_laddr, sizeof (struct in6_addr));
+               memcpy(&npi.npi_foreign_addr_in6,
+                   &inp->in6p_faddr, sizeof (struct in6_addr));
+       }
+
+       npi.npi_owner_pid = so->last_pid;
+
+       if (so->last_pid != 0) {
+               proc_name(so->last_pid, npi.npi_owner_pname,
+                   sizeof(npi.npi_owner_pname));
+       }
+
+       if (so->so_flags & SOF_DELEGATED) {
+               npi.npi_flags |= NPIF_DELEGATED;
+               npi.npi_effective_pid = so->e_pid;
+               if (so->e_pid != 0) {
+                       proc_name(so->e_pid, npi.npi_effective_pname,
+                           sizeof(npi.npi_effective_pname));
+               }
+       } else {
+               npi.npi_effective_pid = so->last_pid;
+               if (so->last_pid != 0) {
+                       strlcpy(npi.npi_effective_pname, npi.npi_owner_pname,
+                           sizeof(npi.npi_effective_pname));
+               }
+       }
+
+       (void) net_port_info_add_entry(&npi);
+}
+
diff --git a/bsd/net/if_ports_used.h b/bsd/net/if_ports_used.h
new file mode 100644 (file)
index 0000000..dc11a10
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017-2018 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+
+#ifndef _NET_IF_PORT_USED_H_
+#define _NET_IF_PORT_USED_H_
+
+#ifdef PRIVATE
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/_types/_timeval32.h>
+#include <netinet/in.h>
+#include <uuid/uuid.h>
+
+#define        IP_PORTRANGE_SIZE 65536
+
+/*
+ * The sysctl "net.link.generic.system.port_used.list" returns:
+ *  - one "struct xnpigen" as a preamble
+ *  - zero or more "struct net_port_info" according to xng_npi_count
+ *
+ * The list may contain information several interfaces if several drivers
+ * queried the list of port to offload
+ *
+ * The same local port may have more than one "struct net_port_info" on
+ * a given interface, for example when a local server has mutiple clients
+ * connections
+ */
+
+struct xnpigen {
+       uint32_t        xng_len; /* length of this data structure */
+       uint32_t        xng_gen; /* how many times the list was built */
+       uint32_t        xng_npi_count; /* number of net_port_info following */
+       uint32_t        xng_npi_size; /* number of struct net_port_info  */
+       uuid_t          xng_wakeuuid; /* WakeUUID when list was built */
+};
+
+union in_addr_4_6 {
+       struct in_addr  _in_a_4;
+       struct in6_addr _in_a_6;
+};
+
+#define        NPIF_IPV4       0x00000001
+#define        NPIF_IPV6       0x00000002
+#define        NPIF_TCP        0x00000004
+#define        NPIF_UDP        0x00000008
+#define        NPIF_DELEGATED  0x00000010
+#define        NPIF_SOCKET     0x00000020
+#define        NPIF_CHANNEL    0x00000040
+
+struct net_port_info {
+       uint16_t                npi_if_index;
+       uint16_t                npi_flags;
+       struct timeval32        npi_timestamp; /* when passed to driver */
+       uuid_t                  npi_flow_uuid;
+       in_port_t               npi_local_port; /* network byte order */
+       in_port_t               npi_foreign_port; /* network byte order */
+       union in_addr_4_6       npi_local_addr_;
+       union in_addr_4_6       npi_foreign_addr_;
+       pid_t                   npi_owner_pid;
+       pid_t                   npi_effective_pid;
+       char                    npi_owner_pname[MAXCOMLEN+1];
+       char                    npi_effective_pname[MAXCOMLEN+1];
+};
+
+#define npi_local_addr_in npi_local_addr_._in_a_4
+#define npi_foreign_addr_in npi_foreign_addr_._in_a_4
+
+#define npi_local_addr_in6 npi_local_addr_._in_a_6
+#define npi_foreign_addr_in6 npi_foreign_addr_._in_a_6
+
+#ifdef XNU_KERNEL_PRIVATE
+
+void if_ports_used_init(void);
+
+void if_ports_used_update_wakeuuid(struct ifnet *);
+
+struct inpcb;
+void if_ports_used_add_inpcb(const uint32_t ifindex, const struct inpcb *inp);
+
+
+#endif /* XNU_KERNEL_PRIVATE */
+#endif /* PRIVATE */ 
+
+#endif /* _NET_IF_PORT_USED_H_ */
index ac4950dd18e14e173212cef7de5f6cc38d27da54..c4fce0074db32d643b705605b73096c021a80760 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -526,10 +526,14 @@ stf_pre_output(
        struct ip6_hdr *ip6;
        struct in6_ifaddr *ia6;
        struct sockaddr_in      *dst4;
-       struct ip_out_args ipoa =
-           { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
-       errno_t                         result = 0;
+       struct ip_out_args ipoa;
+       errno_t result = 0;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        sc = ifnet_softc(ifp);
        dst6 = (const struct sockaddr_in6 *)(const void *)dst;
index ffaa1124c9e82e4326fd578ea9f9866df5691842..ac64bab88ce2c6c5d0ff6fb0d86bbefbe8f2b2dd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -57,8 +57,6 @@ This kernel control will register an interface for every client that connects.
 
 #define UTUN_NEXUS 0
 
-extern unsigned int if_enable_netagent;
-
 #if UTUN_NEXUS
 static nexus_controller_t utun_ncd;
 static int utun_ncd_refcount;
@@ -103,8 +101,10 @@ struct utun_pcb {
        uuid_t                  utun_kpipe_uuid;
        void *                  utun_kpipe_rxring;
        void *                  utun_kpipe_txring;
+       kern_pbufpool_t         utun_kpipe_pp;
 
        kern_nexus_t    utun_netif_nexus;
+       kern_pbufpool_t         utun_netif_pp;
        void *                  utun_netif_rxring;
        void *                  utun_netif_txring;
        uint64_t                utun_netif_txring_size;
@@ -163,6 +163,7 @@ static errno_t utun_pkt_input(struct utun_pcb *pcb, mbuf_t m);
 #define UTUN_IF_DEFAULT_RING_SIZE 64
 #define UTUN_IF_DEFAULT_TX_FSW_RING_SIZE 64
 #define UTUN_IF_DEFAULT_RX_FSW_RING_SIZE 128
+#define UTUN_IF_DEFAULT_BUF_SEG_SIZE   skmem_usr_buf_seg_size
 #define UTUN_IF_HEADROOM_SIZE 32
 
 #define UTUN_IF_MIN_RING_SIZE 16
@@ -588,7 +589,7 @@ utun_netif_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                // Allocate rx packet
                kern_packet_t rx_ph = 0;
                errno_t error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-               if (unlikely(error != 0)) {
+               if (__improbable(error != 0)) {
                        STATS_INC(nifs, NETIF_STATS_NOMEM_PKT);
                        STATS_INC(nifs, NETIF_STATS_DROPPED);
                        lck_mtx_unlock(&pcb->utun_input_chain_lock);
@@ -710,8 +711,11 @@ utun_netif_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                        continue;
                }
 
+               /* XXX We could try this alloc before advancing the slot to avoid
+                * dropping the packet on failure to allocate.
+                */
                errno_t error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-               if (unlikely(error != 0)) {
+               if (__improbable(error != 0)) {
                        STATS_INC(nifs, NETIF_STATS_NOMEM_PKT);
                        STATS_INC(nifs, NETIF_STATS_DROPPED);
                        break;
@@ -809,10 +813,11 @@ utun_nexus_ifattach(struct utun_pcb *pcb,
        errno_t err;
        nexus_controller_t controller = kern_nexus_shared_controller();
        struct kern_nexus_net_init net_init;
+       struct kern_pbufpool_init pp_init;
 
        nexus_name_t provider_name;
        snprintf((char *)provider_name, sizeof(provider_name),
-                        "com.apple.netif.utun%d", pcb->utun_unit);
+                        "com.apple.netif.%s", pcb->utun_if_xname);
 
        struct kern_nexus_provider_init prov_init = {
                .nxpi_version = KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION,
@@ -851,6 +856,21 @@ utun_nexus_ifattach(struct utun_pcb *pcb,
 
        pcb->utun_netif_txring_size = ring_size;
 
+       bzero(&pp_init, sizeof (pp_init));
+       pp_init.kbi_version = KERN_PBUFPOOL_CURRENT_VERSION;
+       pp_init.kbi_packets = pcb->utun_netif_ring_size * 2;
+       pp_init.kbi_bufsize = pcb->utun_slot_size;
+       pp_init.kbi_buf_seg_size = UTUN_IF_DEFAULT_BUF_SEG_SIZE;
+       pp_init.kbi_max_frags = 1;
+       (void) snprintf((char *)pp_init.kbi_name, sizeof (pp_init.kbi_name),
+           "%s", provider_name);
+
+       err = kern_pbufpool_create(&pp_init, &pp_init, &pcb->utun_netif_pp, NULL);
+       if (err != 0) {
+               printf("%s pbufbool create failed, error %d\n", __func__, err);
+               goto failed;
+       }
+
        err = kern_nexus_controller_register_provider(controller,
                                                                                                  utun_nx_dom_prov,
                                                                                                  provider_name,
@@ -870,6 +890,7 @@ utun_nexus_ifattach(struct utun_pcb *pcb,
        net_init.nxneti_eparams = init_params;
        net_init.nxneti_lladdr = NULL;
        net_init.nxneti_prepare = utun_netif_prepare;
+       net_init.nxneti_tx_pbufpool = pcb->utun_netif_pp;
        err = kern_nexus_controller_alloc_net_provider_instance(controller,
                                                                                                                        pcb->utun_nx.if_provider,
                                                                                                                        pcb,
@@ -889,6 +910,10 @@ failed:
        if (nxa) {
                kern_nexus_attr_destroy(nxa);
        }
+       if (err && pcb->utun_netif_pp != NULL) {
+               kern_pbufpool_destroy(pcb->utun_netif_pp);
+               pcb->utun_netif_pp = NULL;
+       }
        return (err);
 }
 
@@ -919,8 +944,9 @@ utun_detach_provider_and_instance(uuid_t provider, uuid_t instance)
 }
 
 static void
-utun_nexus_detach(utun_nx_t nx)
+utun_nexus_detach(struct utun_pcb *pcb)
 {
+       utun_nx_t nx = &pcb->utun_nx;
        nexus_controller_t controller = kern_nexus_shared_controller();
        errno_t err;
 
@@ -949,6 +975,11 @@ utun_nexus_detach(utun_nx_t nx)
        utun_detach_provider_and_instance(nx->ms_provider,
                                                                          nx->ms_instance);
 
+       if (pcb->utun_netif_pp != NULL) {
+               kern_pbufpool_destroy(pcb->utun_netif_pp);
+               pcb->utun_netif_pp = NULL;
+
+       }
        memset(nx, 0, sizeof(*nx));
 }
 
@@ -1090,7 +1121,7 @@ utun_multistack_attach(struct utun_pcb *pcb)
        return (0);
 
 failed:
-       utun_nexus_detach(nx);
+       utun_nexus_detach(pcb);
 
        errno_t detach_error = 0;
        if ((detach_error = ifnet_detach(pcb->utun_ifp)) != 0) {
@@ -1236,6 +1267,10 @@ utun_disable_channel(struct utun_pcb *pcb)
        }
 
        if (!result) {
+               if (pcb->utun_kpipe_pp != NULL) {
+                       kern_pbufpool_destroy(pcb->utun_kpipe_pp);
+                       pcb->utun_kpipe_pp = NULL;
+               }
                utun_unregister_kernel_pipe_nexus();
        }
 
@@ -1246,6 +1281,7 @@ static errno_t
 utun_enable_channel(struct utun_pcb *pcb, struct proc *proc)
 {
        struct kern_nexus_init init;
+       struct kern_pbufpool_init pp_init;
        errno_t result;
 
        result = utun_register_kernel_pipe_nexus();
@@ -1271,9 +1307,27 @@ utun_enable_channel(struct utun_pcb *pcb, struct proc *proc)
                goto done;
        }
 
+       bzero(&pp_init, sizeof (pp_init));
+       pp_init.kbi_version = KERN_PBUFPOOL_CURRENT_VERSION;
+       pp_init.kbi_packets = pcb->utun_netif_ring_size * 2;
+       pp_init.kbi_bufsize = pcb->utun_slot_size;
+       pp_init.kbi_buf_seg_size = UTUN_IF_DEFAULT_BUF_SEG_SIZE;
+       pp_init.kbi_max_frags = 1;
+       pp_init.kbi_flags |= KBIF_QUANTUM;
+       (void) snprintf((char *)pp_init.kbi_name, sizeof (pp_init.kbi_name),
+           "com.apple.kpipe.%s", pcb->utun_if_xname);
+
+       result = kern_pbufpool_create(&pp_init, &pp_init, &pcb->utun_kpipe_pp,
+           NULL);
+       if (result != 0) {
+               printf("%s pbufbool create failed, error %d\n", __func__, result);
+               goto done;
+       }
+
        VERIFY(uuid_is_null(pcb->utun_kpipe_uuid));
        bzero(&init, sizeof (init));
        init.nxi_version = KERN_NEXUS_CURRENT_VERSION;
+       init.nxi_tx_pbufpool = pcb->utun_kpipe_pp;
        result = kern_nexus_controller_alloc_provider_instance(utun_ncd,
                utun_kpipe_uuid, pcb, &pcb->utun_kpipe_uuid, &init);
        if (result) {
@@ -1297,6 +1351,10 @@ done:
        lck_rw_unlock_exclusive(&pcb->utun_pcb_lock);
 
        if (result) {
+               if (pcb->utun_kpipe_pp != NULL) {
+                       kern_pbufpool_destroy(pcb->utun_kpipe_pp);
+                       pcb->utun_kpipe_pp = NULL;
+               }
                utun_unregister_kernel_pipe_nexus();
        }
 
@@ -1786,10 +1844,14 @@ utun_ctl_disconnect(__unused kern_ctl_ref kctlref,
 
                        if (!uuid_is_null(kpipe_uuid)) {
                                if (kern_nexus_controller_free_provider_instance(utun_ncd, kpipe_uuid) == 0) {
+                                       if (pcb->utun_kpipe_pp != NULL) {
+                                               kern_pbufpool_destroy(pcb->utun_kpipe_pp);
+                                               pcb->utun_kpipe_pp = NULL;
+                                       }
                                        utun_unregister_kernel_pipe_nexus();
                                }
                        }
-                       utun_nexus_detach(&pcb->utun_nx);
+                       utun_nexus_detach(pcb);
 
                        /* Decrement refcnt to finish detaching and freeing */
                        ifnet_decr_iorefcnt(ifp);
@@ -1801,6 +1863,10 @@ utun_ctl_disconnect(__unused kern_ctl_ref kctlref,
 #if UTUN_NEXUS
                        if (!uuid_is_null(kpipe_uuid)) {
                                if (kern_nexus_controller_free_provider_instance(utun_ncd, kpipe_uuid) == 0) {
+                                       if (pcb->utun_kpipe_pp != NULL) {
+                                               kern_pbufpool_destroy(pcb->utun_kpipe_pp);
+                                               pcb->utun_kpipe_pp = NULL;
+                                       }
                                        utun_unregister_kernel_pipe_nexus();
                                }
                        }
@@ -2006,7 +2072,7 @@ utun_ctl_setopt(__unused kern_ctl_ref kctlref,
                                result = EINVAL;
                                break;
                        }
-                       if (!if_enable_netagent) {
+                       if (!if_is_netagent_enabled()) {
                                result = ENOTSUP;
                                break;
                        }
@@ -2032,7 +2098,9 @@ utun_ctl_setopt(__unused kern_ctl_ref kctlref,
                                result = EINVAL;
                                break;
                        }
-                       pcb->utun_use_netif = true;
+                       lck_rw_lock_exclusive(&pcb->utun_pcb_lock);
+                       pcb->utun_use_netif = !!(*(int *)data);
+                       lck_rw_unlock_exclusive(&pcb->utun_pcb_lock);
                        break;
                }
                case UTUN_OPT_SLOT_SIZE: {
@@ -2168,6 +2236,37 @@ utun_ctl_getopt(__unused kern_ctl_ref kctlref,
                }
 
 #if UTUN_NEXUS
+               case UTUN_OPT_ENABLE_CHANNEL: {
+                       if (*len != sizeof(int)) {
+                               result = EMSGSIZE;
+                       } else {
+                               lck_rw_lock_shared(&pcb->utun_pcb_lock);
+                               *(int *)data = pcb->utun_kpipe_enabled;
+                               lck_rw_unlock_shared(&pcb->utun_pcb_lock);
+                       }
+                       break;
+               }
+
+               case UTUN_OPT_ENABLE_FLOWSWITCH: {
+                       if (*len != sizeof(int)) {
+                               result = EMSGSIZE;
+                       } else {
+                               *(int *)data = if_check_netagent(pcb->utun_ifp, pcb->utun_nx.ms_agent);
+                       }
+                       break;
+               }
+
+               case UTUN_OPT_ENABLE_NETIF: {
+                       if (*len != sizeof(int)) {
+                               result = EMSGSIZE;
+                       } else {
+                               lck_rw_lock_shared(&pcb->utun_pcb_lock);
+                               *(int *)data = !!pcb->utun_use_netif;
+                               lck_rw_unlock_shared(&pcb->utun_pcb_lock);
+                       }
+                       break;
+               }
+
                case UTUN_OPT_GET_CHANNEL_UUID: {
                        lck_rw_lock_shared(&pcb->utun_pcb_lock);
                        if (uuid_is_null(pcb->utun_kpipe_uuid)) {
@@ -2386,10 +2485,6 @@ utun_demux(__unused ifnet_t interface,
                   __unused char *frame_header,
                   protocol_family_t *protocol)
 {
-       struct utun_pcb *pcb = ifnet_softc(interface);
-       struct ip *ip;
-       u_int ip_version;
-
        while (data != NULL && mbuf_len(data) < 1) {
                data = mbuf_next(data);
        }
@@ -2399,6 +2494,10 @@ utun_demux(__unused ifnet_t interface,
        }
 
 #if UTUN_NEXUS
+       struct utun_pcb *pcb = ifnet_softc(interface);
+       struct ip *ip;
+       u_int ip_version;
+
        if (pcb->utun_use_netif) {
                ip = mtod(data, struct ip *);
                ip_version = ip->ip_v;
@@ -2488,12 +2587,12 @@ utun_ioctl(ifnet_t interface,
                   u_long command,
                   void *data)
 {
-       struct utun_pcb *pcb = ifnet_softc(interface);
        errno_t result = 0;
-       
+
        switch(command) {
                case SIOCSIFMTU: {
 #if UTUN_NEXUS
+                       struct utun_pcb *pcb = ifnet_softc(interface);
                        if (pcb->utun_use_netif) {
                                // Make sure we can fit packets in the channel buffers
                                // Allow for the headroom in the slot
@@ -2544,6 +2643,7 @@ utun_proto_input(__unused ifnet_t interface,
        {
                mbuf_adj(m, UTUN_HEADER_SIZE(pcb));
        }
+    int32_t pktlen = m->m_pkthdr.len;
        if (proto_input(protocol, m) != 0) {
                m_freem(m);
 #if UTUN_NEXUS
@@ -2557,7 +2657,7 @@ utun_proto_input(__unused ifnet_t interface,
                if (!pcb->utun_use_netif)
 #endif // UTUN_NEXUS
                {
-                       ifnet_stat_increment_in(interface, 1, m->m_pkthdr.len, 0);
+                       ifnet_stat_increment_in(interface, 1, pktlen, 0);
                }
        }
        
@@ -2978,7 +3078,7 @@ utun_kpipe_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                        // Allocate rx packet
                        kern_packet_t rx_ph = 0;
                        errno_t error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-                       if (unlikely(error != 0)) {
+                       if (__improbable(error != 0)) {
                                printf("utun_kpipe_sync_rx %s: failed to allocate packet\n",
                                           pcb->utun_ifp->if_xname);
                                break;
@@ -3134,7 +3234,7 @@ utun_kpipe_sync_rx(kern_nexus_provider_t nxprov, kern_nexus_t nexus,
                        // Allocate rx packet
                        kern_packet_t rx_ph = 0;
                        errno_t error = kern_pbufpool_alloc_nosleep(rx_pp, 1, &rx_ph);
-                       if (unlikely(error != 0)) {
+                       if (__improbable(error != 0)) {
                                printf("utun_kpipe_sync_rx %s: failed to allocate packet\n",
                                           pcb->utun_ifp->if_xname);
                                break;
index 60aa09b8fef9e1ef9a38d383f00c1c6ca0871499..835a4535bdc389694687ca010fcd1c88cfdfa8f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -1722,6 +1722,9 @@ __private_extern__ struct rtentry *ifnet_cached_rtlookup_inet6(struct ifnet *,
     struct in6_addr *);
 #endif /* INET6 */
 
+__private_extern__ u_int32_t if_get_protolist(struct ifnet * ifp,
+    u_int32_t *protolist, u_int32_t count);
+__private_extern__ void if_free_protolist(u_int32_t *list);
 __private_extern__ errno_t if_state_update(struct ifnet *,
     struct if_interface_state *);
 __private_extern__ void if_get_state(struct ifnet *,
@@ -1770,6 +1773,8 @@ __private_extern__ u_int32_t ifnet_get_generation(struct ifnet *);
 /* Adding and deleting netagents will take ifnet lock */
 __private_extern__ int if_add_netagent(struct ifnet *, uuid_t);
 __private_extern__ int if_delete_netagent(struct ifnet *, uuid_t);
+__private_extern__ boolean_t if_check_netagent(struct ifnet *, uuid_t);
+
 
 extern int if_set_qosmarking_mode(struct ifnet *, u_int32_t);
 __private_extern__ uint32_t ifnet_mbuf_packetpreamblelen(struct ifnet *);
index 05e7cfc5755de885830f86a943eb656f882428d1..c5f2682138eef5fcc6d42c8240ff6dc58e98f011 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -50,6 +50,7 @@
 #include <net/if_ether.h>
 #include <net/net_api_stats.h>
 #include <net/route.h>
+#include <net/if_ports_used.h>
 #include <libkern/libkern.h>
 #include <libkern/OSAtomic.h>
 #include <kern/locks.h>
@@ -225,16 +226,18 @@ ifnet_allocate_extended(const struct ifnet_init_eparams *einit0,
                }
        }
 
+
+       /* Initialize external name (name + unit) */
+       (void) snprintf(if_xname, sizeof (if_xname), "%s%d",
+           einit.name, einit.unit);
+
        if (einit.uniqueid == NULL) {
-               /* Initialize external name (name + unit) */
-               (void) snprintf(if_xname, sizeof (if_xname), "%s%d",
-                   einit.name, einit.unit);
                einit.uniqueid = if_xname;
                einit.uniqueid_len = strlen(if_xname);
        }
 
        error = dlil_if_acquire(einit.family, einit.uniqueid,
-           einit.uniqueid_len, &ifp);
+           einit.uniqueid_len, if_xname, &ifp);
 
        if (error == 0) {
                u_int64_t br;
@@ -279,7 +282,7 @@ ifnet_allocate_extended(const struct ifnet_init_eparams *einit0,
 
                /* Initialize external name (name + unit) */
                snprintf(__DECONST(char *, ifp->if_xname), IFXNAMSIZ,
-                   "%s%d", ifp->if_name, ifp->if_unit);
+                   "%s", if_xname);
 
                /*
                 * On embedded, framer() is already in the extended form;
@@ -2612,7 +2615,10 @@ ifnet_get_local_ports_extended(ifnet_t ifp, protocol_family_t protocol,
        }
 
        /* bit string is long enough to hold 16-bit port values */
-       bzero(bitfield, bitstr_size(65536));
+       bzero(bitfield, bitstr_size(IP_PORTRANGE_SIZE));
+
+       if_ports_used_update_wakeuuid(ifp);
+
 
                inp_flags |= ((flags & IFNET_GET_LOCAL_PORTS_WILDCARDOK) ?
                        INPCB_GET_PORTS_USED_WILDCARDOK : 0);
@@ -2625,7 +2631,6 @@ ifnet_get_local_ports_extended(ifnet_t ifp, protocol_family_t protocol,
                inp_flags |= ((flags & IFNET_GET_LOCAL_PORTS_ACTIVEONLY) ?
                        INPCB_GET_PORTS_USED_ACTIVEONLY : 0);
 
-               
                ifindex = (ifp != NULL) ? ifp->if_index : 0;
 
                if (!(flags & IFNET_GET_LOCAL_PORTS_TCPONLY))
@@ -2635,6 +2640,7 @@ ifnet_get_local_ports_extended(ifnet_t ifp, protocol_family_t protocol,
                if (!(flags & IFNET_GET_LOCAL_PORTS_UDPONLY))
                        tcp_get_ports_used(ifindex, protocol, inp_flags,
                            bitfield);
+
        return (0);
 }
 
index 22f5afbd54c1df59704e11c1ec6b04e71cdadd3a..1e6a5dcd2a280bd114f814285e6dc1c27f91989d 100644 (file)
@@ -6539,8 +6539,20 @@ necp_application_find_policy_match_internal(proc_t proc,
                                is_local = TRUE;
                        } else if (returned_result->routed_interface_index != 0 &&
                                !no_remote_addr) {
+                               // Clean up the address before comparison with interface addresses
+
+                               // Transform remote_addr into the ifaddr form
+                               // IPv6 Scope IDs are always embedded in the ifaddr list
+                               struct sockaddr_storage remote_address_sanitized;
+                               u_int ifscope = IFSCOPE_NONE;
+                               (void)sa_copy(&remote_addr.sa, &remote_address_sanitized, &ifscope);
+                               SIN(&remote_address_sanitized)->sin_port = 0;
+                               if (remote_address_sanitized.ss_family == AF_INET6) {
+                                       SIN6(&remote_address_sanitized)->sin6_scope_id = 0;
+                               }
+
                                // Check if remote address is an interface address
-                               struct ifaddr *ifa = ifa_ifwithaddr(&remote_addr.sa);
+                               struct ifaddr *ifa = ifa_ifwithaddr((struct sockaddr *)&remote_address_sanitized);
                                if (ifa != NULL && ifa->ifa_ifp != NULL) {
                                        u_int if_index_for_remote_addr = ifa->ifa_ifp->if_index;
                                        if (if_index_for_remote_addr == returned_result->routed_interface_index ||
index 63a9fe9679b1c4b055433c812eb2c4c17b8d4fdf..d20124f6705d15e75e8ad38baa852f8c51d3c28a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2013-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -278,6 +278,8 @@ struct necp_stat_counts
        u_int32_t       necp_stat_avg_rtt;
        u_int32_t       necp_stat_var_rtt;
 
+#define        NECP_STAT_ROUTE_FLAGS   1
+       u_int32_t       necp_stat_route_flags;
 };
 
 // Note, some metadata is implicit in the necp client itself:
@@ -927,7 +929,9 @@ extern void necp_client_early_close(uuid_t client_id); // Cause a single client
 
 extern void necp_set_client_as_background(proc_t proc, struct fileproc *fp, bool background); // Set all clients for an fp as background or not
 
-extern void necp_defunct_client(proc_t proc, struct fileproc *fp); // Set all clients for an fp as defunct
+struct necp_fd_data;
+extern void necp_fd_memstatus(proc_t proc, uint32_t status, struct necp_fd_data *client_fd); // Purge memory of clients for the process
+extern void necp_fd_defunct(proc_t proc, struct necp_fd_data *client_fd); // Set all clients for an process as defunct
 
 extern int necp_client_register_socket_flow(pid_t pid, uuid_t client_id, struct inpcb *inp);
 
@@ -999,6 +1003,10 @@ struct necp_client_flow {
        size_t assigned_results_length;
        u_int8_t *assigned_results;
 };
+
+extern void necp_client_reap_caches(boolean_t);
+
+
 #endif /* BSD_KERNEL_PRIVATE */
 #ifndef KERNEL
 
index 83666005b0843f3088f60ab9b832f37e0cb0ae66..9341db09bbd6486a3f3bd0a08b78f5c5a8ac0636 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2015-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -272,6 +272,7 @@ struct necp_client_nexus_flow_header {
        u_int8_t tfo_cookie_value[NECP_TFO_COOKIE_LEN_MAX];
 } __attribute__((__packed__));
 
+
 struct necp_client {
        RB_ENTRY(necp_client) link;
        RB_ENTRY(necp_client) global_link;
@@ -363,6 +364,7 @@ struct necp_client_update {
        struct necp_client_observer_update update;
 };
 
+
 struct necp_fd_data {
        u_int8_t necp_fd_type;
        LIST_ENTRY(necp_fd_data) chain;
@@ -392,8 +394,9 @@ static struct zone *necp_client_fd_zone;    /* zone for necp_fd_data */
 #define        NECP_FLOW_ZONE_MAX                      512
 #define        NECP_FLOW_ZONE_NAME                     "necp.flow"
 
-static unsigned int necp_flow_size;                    /* size of zone element */
-static struct zone *necp_flow_zone;                    /* zone for necp_client_flow */
+static unsigned int necp_flow_size;            /* size of necp_client_flow */
+static struct mcache *necp_flow_cache;         /* cache for necp_client_flow */
+
 
 static lck_grp_attr_t  *necp_fd_grp_attr       = NULL;
 static lck_attr_t              *necp_fd_mtx_attr       = NULL;
@@ -695,6 +698,10 @@ necp_set_client_defunct(struct necp_client *client)
 
                (void)necp_buffer_write_tlv_if_different(client->result, NECP_CLIENT_RESULT_FLAGS,
                                                                                                 sizeof(flags), &flags, &updated, client->result, sizeof(client->result));
+
+        if (updated) {
+            client->result_read = FALSE;
+        }
        }
 
        return (updated);
@@ -704,6 +711,8 @@ static void
 necp_defunct_client_for_policy(struct necp_client *client,
                                                           struct _necp_client_defunct_list *defunct_list)
 {
+       NECP_CLIENT_ASSERT_LOCKED(client);
+       
        if (!client->defunct) {
                bool needs_defunct = false;
                struct necp_client_flow *search_flow = NULL;
@@ -958,7 +967,7 @@ necp_destroy_client(struct necp_client *client, pid_t pid, bool abort)
                } else {
                        OSDecrementAtomic(&necp_if_flow_count);
                }
-               zfree(necp_flow_zone, search_flow);
+               mcache_free(necp_flow_cache, search_flow);
        }
 
        // Remove agent assertions
@@ -1088,7 +1097,7 @@ done:
 static void
 necp_client_add_socket_flow(struct necp_client *client, struct inpcb *inp)
 {
-       struct necp_client_flow *new_flow = zalloc(necp_flow_zone);
+       struct necp_client_flow *new_flow = mcache_alloc(necp_flow_cache, MCR_SLEEP);
        if (new_flow == NULL) {
                NECPLOG0(LOG_ERR, "Failed to allocate socket flow");
                return;
@@ -1108,7 +1117,7 @@ necp_client_add_socket_flow(struct necp_client *client, struct inpcb *inp)
 static void
 necp_client_add_interface_flow(struct necp_client *client, uint32_t interface_index)
 {
-       struct necp_client_flow *new_flow = zalloc(necp_flow_zone);
+       struct necp_client_flow *new_flow = mcache_alloc(necp_flow_cache, MCR_SLEEP);
        if (new_flow == NULL) {
                NECPLOG0(LOG_ERR, "Failed to allocate interface flow");
                return;
@@ -1170,8 +1179,13 @@ necp_client_flow_is_viable(proc_t proc, struct necp_client *client,
 }
 
 static bool
-necp_client_update_flows(proc_t proc, struct necp_client *client)
+necp_client_update_flows(proc_t proc,
+                                                struct necp_client *client,
+                                                struct _necp_client_defunct_list *defunct_list,
+                                                bool *defuncted_by_flow)
 {
+       NECP_CLIENT_ASSERT_LOCKED(client);
+
        bool client_updated = FALSE;
        struct necp_client_flow *flow = NULL;
        struct necp_client_flow *temp_flow = NULL;
@@ -1205,6 +1219,8 @@ necp_client_update_flows(proc_t proc, struct necp_client *client)
                        // check again the flags after the callback.
                }
 
+               (void)defunct_list;
+               (void)defuncted_by_flow;
 
                // Handle flows that no longer match
                if (!flow->viable || flow->invalid) {
@@ -1221,7 +1237,7 @@ necp_client_update_flows(proc_t proc, struct necp_client *client)
                                } else {
                                        OSDecrementAtomic(&necp_if_flow_count);
                                }
-                               zfree(necp_flow_zone, flow);
+                               mcache_free(necp_flow_cache, flow);
                        }
                }
        }
@@ -1775,7 +1791,7 @@ necp_client_unregister_socket_flow(uuid_t client_id, void *handle)
                                        client_updated = TRUE;
                                        LIST_REMOVE(search_flow, flow_chain);
                                        OSDecrementAtomic(&necp_socket_flow_count);
-                                       zfree(necp_flow_zone, search_flow);
+                                       mcache_free(necp_flow_cache, search_flow);
                                }
                        }
 
@@ -2013,7 +2029,13 @@ necp_update_flow_protoctl_event(uuid_t netagent_uuid, uuid_t client_id,
 }
 
 static bool
-necp_assign_client_result_locked(struct proc *proc, struct necp_fd_data *client_fd, struct necp_client *client, uuid_t netagent_uuid, u_int8_t *assigned_results, size_t assigned_results_length)
+necp_assign_client_result_locked(struct proc *proc,
+                                                                struct necp_fd_data *client_fd,
+                                                                struct necp_client *client,
+                                                                uuid_t netagent_uuid,
+                                                                u_int8_t *assigned_results,
+                                                                size_t assigned_results_length,
+                                                                bool notify_fd)
 {
        bool client_updated = FALSE;
 
@@ -2048,7 +2070,7 @@ necp_assign_client_result_locked(struct proc *proc, struct necp_fd_data *client_
                }
        }
 
-       if (client_updated) {
+       if (client_updated && notify_fd) {
                necp_fd_notify(client_fd, true);
        }
 
@@ -2079,7 +2101,8 @@ necp_assign_client_result(uuid_t netagent_uuid, uuid_t client_id,
                        // Found the right client!
                        found_client = TRUE;
 
-                       if (necp_assign_client_result_locked(proc, client_fd, client, netagent_uuid, assigned_results, assigned_results_length)) {
+                       if (necp_assign_client_result_locked(proc, client_fd, client, netagent_uuid,
+                                                                                                assigned_results, assigned_results_length, true)) {
                                client_updated = TRUE;
                        }
 
@@ -2422,8 +2445,14 @@ necp_update_client_result(proc_t proc,
        }
 
        // Update flow viability/flags
-       if (necp_client_update_flows(proc, client)) {
+       bool defuncted_by_flow = FALSE;
+       if (necp_client_update_flows(proc, client, defunct_list, &defuncted_by_flow)) {
                updated = TRUE;
+               if (defuncted_by_flow && client->defunct) {
+                       // Reset initial TLV
+                       flags |= NECP_CLIENT_RESULT_FLAG_DEFUNCT;
+                       (void)necp_buffer_write_tlv_if_different(client->result, NECP_CLIENT_RESULT_FLAGS, sizeof(flags), &flags, &updated, client->result, sizeof(client->result));
+               }
        }
 
        if (updated) {
@@ -2436,12 +2465,14 @@ necp_update_client_result(proc_t proc,
 }
 
 static inline void
-necp_defunct_client_fd_locked(struct necp_fd_data *client_fd, struct _necp_client_defunct_list *defunct_list)
+necp_defunct_client_fd_locked(struct necp_fd_data *client_fd, struct _necp_client_defunct_list *defunct_list, struct proc *proc)
 {
+#pragma unused(proc)
        bool updated_result = FALSE;
        struct necp_client *client = NULL;
 
        NECP_FD_ASSERT_LOCKED(client_fd);
+
        RB_FOREACH(client, _necp_client_tree, &client_fd->clients) {
                NECP_CLIENT_LOCK(client);
                if (!client->defunct) {
@@ -2469,6 +2500,8 @@ necp_defunct_client_fd_locked(struct necp_fd_data *client_fd, struct _necp_clien
                }
                NECP_CLIENT_UNLOCK(client);
        }
+
+
        if (updated_result) {
                necp_fd_notify(client_fd, true);
        }
@@ -2536,7 +2569,10 @@ necp_update_all_clients_callout(__unused thread_call_param_t dummy,
                                                                                                                         client_defunct->proc_pid,
                                                                                                                         NETAGENT_MESSAGE_TYPE_ABORT_NEXUS);
                                if (netagent_error != 0) {
-                                       NECPLOG((netagent_error == ENOENT ? LOG_DEBUG : LOG_ERR), "necp_update_client abort nexus error (%d)", netagent_error);
+                                       char namebuf[MAXCOMLEN+1];
+                                       (void) strlcpy(namebuf, "unknown", sizeof (namebuf));
+                                       proc_name(client_defunct->proc_pid, namebuf, sizeof (namebuf));
+                                       NECPLOG((netagent_error == ENOENT ? LOG_DEBUG : LOG_ERR), "necp_update_client abort nexus error (%d) for pid %d %s", netagent_error, client_defunct->proc_pid, namebuf);
                                }
                        }
                        LIST_REMOVE(client_defunct, chain);
@@ -2622,26 +2658,24 @@ necp_set_client_as_background(proc_t proc,
 }
 
 void
-necp_defunct_client(proc_t proc,
-                                       struct fileproc *fp)
+necp_fd_memstatus(proc_t proc, uint32_t status,
+    struct necp_fd_data *client_fd)
 {
-       struct _necp_client_defunct_list defunct_list;
+#pragma unused(proc, status, client_fd)
+       ASSERT(proc != PROC_NULL);
+       ASSERT(client_fd != NULL);
 
-       if (proc == PROC_NULL) {
-               NECPLOG0(LOG_ERR, "NULL proc passed to set as background");
-               return;
-       }
+       // Nothing to reap for the process or client for now,
+       // but this is where we would trigger that in future.
+}
 
-       if (fp == NULL) {
-               NECPLOG0(LOG_ERR, "NULL fp passed to set as background");
-               return;
-       }
+void
+necp_fd_defunct(proc_t proc, struct necp_fd_data *client_fd)
+{
+       struct _necp_client_defunct_list defunct_list;
 
-       struct necp_fd_data *client_fd = (struct necp_fd_data *)fp->f_fglob->fg_data;
-       if (client_fd == NULL) {
-               NECPLOG0(LOG_ERR, "Could not find client structure for backgrounded client");
-               return;
-       }
+       ASSERT(proc != PROC_NULL);
+       ASSERT(client_fd != NULL);
 
        if (client_fd->necp_fd_type != necp_fd_type_client) {
                // Not a client fd, ignore
@@ -2653,7 +2687,7 @@ necp_defunct_client(proc_t proc,
 
        // Need to hold lock so ntstats defunct the same set of clients
        NECP_FD_LOCK(client_fd);
-       necp_defunct_client_fd_locked(client_fd, &defunct_list);
+       necp_defunct_client_fd_locked(client_fd, &defunct_list, proc);
        NECP_FD_UNLOCK(client_fd);
 
        if (!LIST_EMPTY(&defunct_list)) {
@@ -3307,7 +3341,7 @@ necp_client_remove(struct necp_fd_data *fd_data, struct necp_client_action_args
 {
        int error = 0;
        struct necp_client *client = NULL;
-       struct necp_client *temp_client = NULL;
+       struct necp_client find = {};
        uuid_t client_id = {};
        struct ifnet_stats_per_flow flow_ifnet_stats = {};
 
@@ -3326,33 +3360,36 @@ necp_client_remove(struct necp_fd_data *fd_data, struct necp_client_action_args
                error = copyin(uap->buffer, &flow_ifnet_stats, uap->buffer_size);
                if (error) {
                        NECPLOG(LOG_ERR, "necp_client_remove flow_ifnet_stats copyin error (%d)", error);
-                       // Not fatal
+                       // Not fatal; make sure to zero-out stats in case of partial copy
+                       memset(&flow_ifnet_stats, 0, sizeof (flow_ifnet_stats));
+                       error = 0;
                }
        } else if (uap->buffer != 0) {
                NECPLOG(LOG_ERR, "necp_client_remove unexpected parameters length (%zu)", uap->buffer_size);
        }
 
-       struct _necp_client_tree clients_to_close;
-       RB_INIT(&clients_to_close);
        NECP_FD_LOCK(fd_data);
+
        pid_t pid = fd_data->proc_pid;
-       RB_FOREACH_SAFE(client, _necp_client_tree, &fd_data->clients, temp_client) {
-               if (uuid_compare(client->client_id, client_id) == 0) {
-                       NECP_CLIENT_TREE_LOCK_EXCLUSIVE();
-                       RB_REMOVE(_necp_client_global_tree, &necp_client_global_tree, client);
-                       NECP_CLIENT_TREE_UNLOCK();
-                       RB_REMOVE(_necp_client_tree, &fd_data->clients, client);
-                       RB_INSERT(_necp_client_tree, &clients_to_close, client);
-               }
+       uuid_copy(find.client_id, client_id);
+       client = RB_FIND(_necp_client_tree, &fd_data->clients, &find);
+       if (client != NULL) {
+               NECP_CLIENT_TREE_LOCK_EXCLUSIVE();
+               RB_REMOVE(_necp_client_global_tree, &necp_client_global_tree, client);
+               NECP_CLIENT_TREE_UNLOCK();
+               RB_REMOVE(_necp_client_tree, &fd_data->clients, client);
        }
 
-
        NECP_FD_UNLOCK(fd_data);
 
-       RB_FOREACH_SAFE(client, _necp_client_tree, &clients_to_close, temp_client) {
-               RB_REMOVE(_necp_client_tree, &clients_to_close, client);
+       if (client != NULL) {
+               ASSERT(error == 0);
                necp_destroy_client(client, pid, true);
+       } else {
+               error = ENOENT;
+               NECPLOG(LOG_ERR, "necp_client_remove invalid client_id (%d)", error);
        }
+
 done:
        *retval = error;
 
@@ -3646,7 +3683,6 @@ static int
 necp_client_copy(struct necp_fd_data *fd_data, struct necp_client_action_args *uap, int *retval)
 {
        int error = 0;
-       struct necp_client *find_client = NULL;
        struct necp_client *client = NULL;
        uuid_t client_id;
        uuid_clear(client_id);
@@ -3679,28 +3715,34 @@ necp_client_copy(struct necp_fd_data *fd_data, struct necp_client_action_args *u
                }
        }
 
+       const bool is_wildcard = (bool)uuid_is_null(client_id);
+
        NECP_FD_LOCK(fd_data);
-       RB_FOREACH(find_client, _necp_client_tree, &fd_data->clients) {
-               NECP_CLIENT_LOCK(find_client);
-               if ((uap->action == NECP_CLIENT_ACTION_COPY_RESULT || uap->action == NECP_CLIENT_ACTION_COPY_UPDATED_RESULT) &&
-                       uuid_is_null(client_id)) {
-                       if (!find_client->result_read || !find_client->flow_result_read) {
-                               client = find_client;
+
+       if (is_wildcard) {
+               if (uap->action == NECP_CLIENT_ACTION_COPY_RESULT || uap->action == NECP_CLIENT_ACTION_COPY_UPDATED_RESULT) {
+                       struct necp_client *find_client = NULL;
+                       RB_FOREACH(find_client, _necp_client_tree, &fd_data->clients) {
+                               NECP_CLIENT_LOCK(find_client);
+                               if (!find_client->result_read || !find_client->flow_result_read) {
+                                       client = find_client;
+                                       // Leave the client locked, and break
+                                       break;
+                               }
+                               NECP_CLIENT_UNLOCK(find_client);
                        }
-               } else if (uuid_compare(find_client->client_id, client_id) == 0) {
-                       client = find_client;
-               }
-               NECP_CLIENT_UNLOCK(find_client);
-               if (client != NULL) {
-                       break;
                }
+       } else {
+               client = necp_client_fd_find_client_and_lock(fd_data, client_id);
        }
 
        if (client != NULL) {
+               // If client is set, it is locked
                error = necp_client_copy_internal(client, FALSE, uap, retval);
+               NECP_CLIENT_UNLOCK(client);
        }
 
-       // Unlock our own client before moving on or returning
+       // Unlock our own fd before moving on or returning
        NECP_FD_UNLOCK(fd_data);
 
        if (client == NULL) {
@@ -4016,6 +4058,7 @@ necp_client_agent_action(struct necp_fd_data *fd_data, struct necp_client_action
 
        if (uap->client_id == 0 || uap->client_id_len != sizeof(uuid_t) ||
                uap->buffer_size == 0 || uap->buffer == 0) {
+               NECPLOG0(LOG_ERR, "necp_client_agent_action invalid parameters");
                error = EINVAL;
                goto done;
        }
@@ -4027,6 +4070,7 @@ necp_client_agent_action(struct necp_fd_data *fd_data, struct necp_client_action
        }
 
        if ((parameters = _MALLOC(uap->buffer_size, M_NECP, M_WAITOK | M_ZERO)) == NULL) {
+               NECPLOG0(LOG_ERR, "necp_client_agent_action malloc failed");
                error = ENOMEM;
                goto done;
        }
@@ -4313,21 +4357,22 @@ necp_client_copy_route_statistics(__unused struct necp_fd_data *fd_data, struct
        client = necp_client_fd_find_client_and_lock(fd_data, client_id);
        if (client != NULL) {
                NECP_CLIENT_ROUTE_LOCK(client);
-               struct nstat_counts route_stats = {};
+               struct necp_stat_counts route_stats = {};
                if (client->current_route != NULL && client->current_route->rt_stats != NULL) {
                        struct nstat_counts     *rt_stats = client->current_route->rt_stats;
-                       atomic_get_64(route_stats.nstat_rxpackets, &rt_stats->nstat_rxpackets);
-                       atomic_get_64(route_stats.nstat_rxbytes, &rt_stats->nstat_rxbytes);
-                       atomic_get_64(route_stats.nstat_txpackets, &rt_stats->nstat_txpackets);
-                       atomic_get_64(route_stats.nstat_txbytes, &rt_stats->nstat_txbytes);
-                       route_stats.nstat_rxduplicatebytes = rt_stats->nstat_rxduplicatebytes;
-                       route_stats.nstat_rxoutoforderbytes = rt_stats->nstat_rxoutoforderbytes;
-                       route_stats.nstat_txretransmit = rt_stats->nstat_txretransmit;
-                       route_stats.nstat_connectattempts = rt_stats->nstat_connectattempts;
-                       route_stats.nstat_connectsuccesses = rt_stats->nstat_connectsuccesses;
-                       route_stats.nstat_min_rtt = rt_stats->nstat_min_rtt;
-                       route_stats.nstat_avg_rtt = rt_stats->nstat_avg_rtt;
-                       route_stats.nstat_var_rtt = rt_stats->nstat_var_rtt;
+                       atomic_get_64(route_stats.necp_stat_rxpackets, &rt_stats->nstat_rxpackets);
+                       atomic_get_64(route_stats.necp_stat_rxbytes, &rt_stats->nstat_rxbytes);
+                       atomic_get_64(route_stats.necp_stat_txpackets, &rt_stats->nstat_txpackets);
+                       atomic_get_64(route_stats.necp_stat_txbytes, &rt_stats->nstat_txbytes);
+                       route_stats.necp_stat_rxduplicatebytes = rt_stats->nstat_rxduplicatebytes;
+                       route_stats.necp_stat_rxoutoforderbytes = rt_stats->nstat_rxoutoforderbytes;
+                       route_stats.necp_stat_txretransmit = rt_stats->nstat_txretransmit;
+                       route_stats.necp_stat_connectattempts = rt_stats->nstat_connectattempts;
+                       route_stats.necp_stat_connectsuccesses = rt_stats->nstat_connectsuccesses;
+                       route_stats.necp_stat_min_rtt = rt_stats->nstat_min_rtt;
+                       route_stats.necp_stat_avg_rtt = rt_stats->nstat_avg_rtt;
+                       route_stats.necp_stat_var_rtt = rt_stats->nstat_var_rtt;
+                       route_stats.necp_stat_route_flags = client->current_route->rt_flags;
                }
 
                // Unlock before copying out
@@ -4828,6 +4873,7 @@ necp_inpcb_remove_cb(struct inpcb *inp)
 void
 necp_inpcb_dispose(struct inpcb *inp)
 {
+       necp_inpcb_remove_cb(inp); // Clear out socket registrations if not yet done
        if (inp->inp_necp_attributes.inp_domain != NULL) {
                FREE(inp->inp_necp_attributes.inp_domain, M_NECP);
                inp->inp_necp_attributes.inp_domain = NULL;
@@ -4852,27 +4898,22 @@ necp_mppcb_dispose(struct mppcb *mpp)
 errno_t
 necp_client_init(void)
 {
-       errno_t result = 0;
-
        necp_fd_grp_attr = lck_grp_attr_alloc_init();
        if (necp_fd_grp_attr == NULL) {
-               NECPLOG0(LOG_ERR, "lck_grp_attr_alloc_init failed");
-               result = ENOMEM;
-               goto done;
+               panic("lck_grp_attr_alloc_init failed\n");
+               /* NOTREACHED */
        }
 
        necp_fd_mtx_grp = lck_grp_alloc_init("necp_fd", necp_fd_grp_attr);
        if (necp_fd_mtx_grp == NULL) {
-               NECPLOG0(LOG_ERR, "lck_grp_alloc_init failed");
-               result = ENOMEM;
-               goto done;
+               panic("lck_grp_alloc_init failed\n");
+               /* NOTREACHED */
        }
 
        necp_fd_mtx_attr = lck_attr_alloc_init();
        if (necp_fd_mtx_attr == NULL) {
-               NECPLOG0(LOG_ERR, "lck_attr_alloc_init failed");
-               result = ENOMEM;
-               goto done;
+               panic("lck_attr_alloc_init failed\n");
+               /* NOTREACHED */
        }
 
        necp_client_fd_size = sizeof(struct necp_fd_data);
@@ -4880,19 +4921,15 @@ necp_client_init(void)
                                                                NECP_CLIENT_FD_ZONE_MAX * necp_client_fd_size,
                                                                0, NECP_CLIENT_FD_ZONE_NAME);
        if (necp_client_fd_zone == NULL) {
-               NECPLOG0(LOG_ERR, "zinit(necp_client_fd) failed");
-               result = ENOMEM;
-               goto done;
+               panic("zinit(necp_client_fd) failed\n");
+               /* NOTREACHED */
        }
 
        necp_flow_size = sizeof(struct necp_client_flow);
-       necp_flow_zone = zinit(necp_flow_size,
-                                                  NECP_FLOW_ZONE_MAX * necp_flow_size,
-                                                  0, NECP_FLOW_ZONE_NAME);
-       if (necp_flow_zone == NULL) {
-               NECPLOG0(LOG_ERR, "zinit(necp_flow) failed");
-               result = ENOMEM;
-               goto done;
+       necp_flow_cache = mcache_create(NECP_FLOW_ZONE_NAME, necp_flow_size, sizeof (uint64_t), 0, MCR_SLEEP);
+       if (necp_flow_cache == NULL) {
+               panic("mcache_create(necp_flow_cache) failed\n");
+               /* NOTREACHED */
        }
 
        necp_client_update_tcall = thread_call_allocate_with_options(necp_update_all_clients_callout, NULL,
@@ -4910,20 +4947,12 @@ necp_client_init(void)
 
        RB_INIT(&necp_client_global_tree);
 
-done:
-       if (result != 0) {
-               if (necp_fd_mtx_attr != NULL) {
-                       lck_attr_free(necp_fd_mtx_attr);
-                       necp_fd_mtx_attr = NULL;
-               }
-               if (necp_fd_mtx_grp != NULL) {
-                       lck_grp_free(necp_fd_mtx_grp);
-                       necp_fd_mtx_grp = NULL;
-               }
-               if (necp_fd_grp_attr != NULL) {
-                       lck_grp_attr_free(necp_fd_grp_attr);
-                       necp_fd_grp_attr = NULL;
-               }
-       }
-       return (result);
+       return (0);
+}
+
+void
+necp_client_reap_caches(boolean_t purge)
+{
+       mcache_reap_now(necp_flow_cache, purge);
 }
+
index 137682285d1097e37a492f0cd9a399ee15ea941c..36385a019ed69e189d6c641469bc426af46b4416 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2012-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -28,8 +28,6 @@
 
 #include <kern/debug.h>
 
-#if !NETWORKING
-
 #define        STUB(name)                                                      \
        int name(void);                                                 \
        int name(void)                                                  \
@@ -38,6 +36,8 @@
                return (0);                                             \
        }
 
+#if !NETWORKING
+
 STUB(bpf_attach);
 STUB(bpf_tap_in);
 STUB(bpf_tap_out);
@@ -467,4 +467,7 @@ void m_drain(void)
        return;
 }
 
+#else /* NETWORKING */
+
+
 #endif /* !NETWORKING */
index 14fe6dc995631320bab1864d9eae3a3e23670f27..392665f18c2d5b04a0eab98dd3cfbd9ba1acd18d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2014-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -811,7 +811,7 @@ netagent_handle_register_setopt(struct netagent_session *session, u_int8_t *payl
        }
 
        if (payload_length < sizeof(struct netagent)) {
-               NETAGENTLOG(LOG_ERR, "Register message size too small for agent: (%d < %d)",
+               NETAGENTLOG(LOG_ERR, "Register message size too small for agent: (%u < %lu)",
                                        payload_length, sizeof(struct netagent));
                response_error = EINVAL;
                goto done;
@@ -825,7 +825,7 @@ netagent_handle_register_setopt(struct netagent_session *session, u_int8_t *payl
        }
 
        if (payload_length != (sizeof(struct netagent) + data_size)) {
-               NETAGENTLOG(LOG_ERR, "Mismatch between data size and payload length (%u != %u)", (sizeof(struct netagent) + data_size), payload_length);
+               NETAGENTLOG(LOG_ERR, "Mismatch between data size and payload length (%lu != %u)", (sizeof(struct netagent) + data_size), payload_length);
                response_error = EINVAL;
                goto done;
     }
@@ -877,7 +877,7 @@ netagent_handle_register_message(struct netagent_session *session, u_int32_t mes
        }
 
        if (payload_length < sizeof(struct netagent)) {
-               NETAGENTLOG(LOG_ERR, "Register message size too small for agent: (%d < %d)",
+               NETAGENTLOG(LOG_ERR, "Register message size too small for agent: (%u < %lu)",
                                        payload_length, sizeof(struct netagent));
                response_error = NETAGENT_MESSAGE_ERROR_INVALID_DATA;
                goto fail;
@@ -1158,7 +1158,7 @@ netagent_handle_update_setopt(struct netagent_session *session, u_int8_t *payloa
        }
 
        if (payload_length < sizeof(struct netagent)) {
-               NETAGENTLOG(LOG_ERR, "Update message size too small for agent: (%d < %d)",
+               NETAGENTLOG(LOG_ERR, "Update message size too small for agent: (%u < %lu)",
                                        payload_length, sizeof(struct netagent));
                response_error = EINVAL;
                goto done;
@@ -1172,7 +1172,7 @@ netagent_handle_update_setopt(struct netagent_session *session, u_int8_t *payloa
        }
 
        if (payload_length != (sizeof(struct netagent) + data_size)) {
-               NETAGENTLOG(LOG_ERR, "Mismatch between data size and payload length (%u != %u)", (sizeof(struct netagent) + data_size), payload_length);
+               NETAGENTLOG(LOG_ERR, "Mismatch between data size and payload length (%lu != %u)", (sizeof(struct netagent) + data_size), payload_length);
                response_error = EINVAL;
                goto done;
     }
@@ -1225,7 +1225,7 @@ netagent_handle_update_message(struct netagent_session *session, u_int32_t messa
        }
 
        if (payload_length < sizeof(struct netagent)) {
-               NETAGENTLOG(LOG_ERR, "Update message size too small for agent: (%d < %d)",
+               NETAGENTLOG(LOG_ERR, "Update message size too small for agent: (%u < %lu)",
                                        payload_length, sizeof(struct netagent));
                response_error = NETAGENT_MESSAGE_ERROR_INVALID_DATA;
                goto fail;
@@ -1526,7 +1526,7 @@ netagent_handle_use_count_setopt(struct netagent_session *session, u_int8_t *pay
        }
 
        if (payload_length != sizeof(use_count)) {
-               NETAGENTLOG(LOG_ERR, "Payload length is invalid (%u)", payload_length);
+               NETAGENTLOG(LOG_ERR, "Payload length is invalid (%lu)", payload_length);
                response_error = EINVAL;
                goto done;
        }
@@ -1569,7 +1569,7 @@ netagent_handle_use_count_getopt(struct netagent_session *session, u_int8_t *buf
        }
 
        if (*buffer_length != sizeof(use_count)) {
-               NETAGENTLOG(LOG_ERR, "Buffer length is invalid (%u)", buffer_length);
+               NETAGENTLOG(LOG_ERR, "Buffer length is invalid (%lu)", *buffer_length);
                response_error = EINVAL;
                goto done;
        }
@@ -1985,6 +1985,11 @@ netagent_client_message_with_params(uuid_t agent_uuid,
                }
        }
        NETAGENTLOG(((error && error != ENOENT) ? LOG_ERR : LOG_INFO), "Send message %d for client (error %d)", message_type, error);
+       if (message_type == NETAGENT_MESSAGE_TYPE_CLIENT_TRIGGER) {
+               uuid_string_t uuid_str;
+               uuid_unparse(agent_uuid, uuid_str);
+               NETAGENTLOG(LOG_NOTICE, "Triggered network agent %s, error = %d", uuid_str, error);
+       }
 done:
        if (should_unlock) {
                lck_rw_done(&netagent_lock);
@@ -2065,7 +2070,7 @@ netagent_trigger(struct proc *p, struct netagent_trigger_args *uap, int32_t *ret
 
        if (uap->agent_uuid) {
                if (uap->agent_uuidlen != sizeof(uuid_t)) {
-                       NETAGENTLOG(LOG_ERR, "Incorrect length (got %d, expected %d)",
+                       NETAGENTLOG(LOG_ERR, "Incorrect length (got %llu, expected %lu)",
                                                uap->agent_uuidlen, sizeof(uuid_t));
                        return (ERANGE);
                }
index 1d51a92e775eb50dab22a16d05878fdc8a0d5a03..e370d7c937fcc5cdca5574a0794bee98dd0fe07e 100644 (file)
@@ -77,8 +77,6 @@
 #include <netinet6/in6_pcb.h>
 #include <netinet6/in6_var.h>
 
-extern unsigned int if_enable_netagent;
-
 __private_extern__ int nstat_collect = 1;
 
 #if (DEBUG || DEVELOPMENT)
index 6ce23690e70fd384b3345e438d5a9b49f70d89e9..0ddbf167a68358c2915779bab18ce0f1f3862cc0 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (c) 2007-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
@@ -2961,7 +2961,8 @@ pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
                        if (f->child->match ||
                            (match != NULL && *match)) {
                                f->r->anchor->match = 1;
-                               *match = 0;
+                               if (match)
+                                       *match = 0;
                        }
                        f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
                        if (f->child != NULL) {
index d83fbb25347631baef0f874de391bf2667c3be07..01a6c7cc927db580f77b29d601e345b9c58dc534 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -543,7 +543,7 @@ tcq_addq(struct tcq_class *cl, pktsched_pkt_t *pkt, struct pf_mtag *t)
 
 #if PF_ECN
        if (cl->cl_flags & TQCF_CLEARDSCP)
-               /* not supported for skywalk packets */
+               /* not supported for non-BSD stack packets */
                VERIFY(pkt->pktsched_ptype == QP_MBUF);
                write_dsfield(m, t, 0);
 #endif /* PF_ECN */
index 80d336a400505ceba76740bec05de167faea2a9f..69fdd5937655eaee0723bf8aea04c3c1185cfbee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -74,6 +74,7 @@
 #include <sys/syslog.h>
 #include <sys/queue.h>
 #include <sys/mcache.h>
+#include <sys/priv.h>
 #include <sys/protosw.h>
 #include <sys/kernel.h>
 #include <kern/locks.h>
@@ -1485,8 +1486,14 @@ create:
 done:
        if (rt != NULL) {
                RT_LOCK_ASSERT_NOTHELD(rt);
-               if (rtp && !error)
-                       *rtp = rt;
+               if (!error) {
+                       /* Enqueue event to refresh flow route entries */
+                       route_event_enqueue_nwk_wq_entry(rt, NULL, ROUTE_ENTRY_REFRESH, NULL, FALSE);
+                       if (rtp)
+                               *rtp = rt;
+                       else
+                               rtfree_locked(rt);
+               }
                else
                        rtfree_locked(rt);
        }
@@ -4364,4 +4371,38 @@ route_event2str(int route_event)
        return  route_event_str;
 }
 
-
+int
+route_op_entitlement_check(struct socket *so,
+    kauth_cred_t cred,
+    int route_op_type,
+    boolean_t allow_root)
+{
+       if (so != NULL) {
+               if (route_op_type == ROUTE_OP_READ) {
+                       /*
+                        * If needed we can later extend this for more
+                        * granular entitlements and return a bit set of
+                        * allowed accesses.
+                        */
+                       if (soopt_cred_check(so, PRIV_NET_RESTRICTED_ROUTE_NC_READ,
+                           allow_root) == 0)
+                               return (0);
+                       else
+                               return (-1);
+               }
+       } else if (cred != NULL) {
+               uid_t uid = kauth_cred_getuid(cred);
+
+               /* uid is 0 for root */
+               if (uid != 0 || !allow_root) {
+                       if (route_op_type == ROUTE_OP_READ) {
+                               if (priv_check_cred(cred,
+                                   PRIV_NET_RESTRICTED_ROUTE_NC_READ, 0) == 0)
+                                       return (0);
+                               else
+                                       return (-1);
+                       }
+               }
+       }
+       return (-1);
+}
index 1e01812ecd3b6e41ba7e3857027699fddd13ec30..141381e0ae3d5a467b813106b11f4606decae957 100644 (file)
@@ -272,6 +272,12 @@ EVENTHANDLER_DECLARE(route_event, route_event_fn);
        ((_rt)->rt_tree_genid != NULL &&                                \
        *(_rt)->rt_tree_genid != (_rt)->rt_genid)
 
+enum {
+       ROUTE_OP_READ,
+       ROUTE_OP_WRITE,
+};
+
+extern int route_op_entitlement_check(struct socket *, kauth_cred_t, int, boolean_t);
 #endif /* BSD_KERNEL_PRIVATE */
 
 #define        RTF_UP          0x1             /* route usable */
@@ -677,6 +683,5 @@ extern void route_event_init(struct route_event *p_route_ev, struct rtentry *rt,
 extern int route_event_walktree(struct radix_node *rn, void *arg);
 extern void route_event_enqueue_nwk_wq_entry(struct rtentry *, struct rtentry *,
     uint32_t, eventhandler_tag, boolean_t);
-
 #endif /* BSD_KERNEL_PRIVATE */
 #endif /* _NET_ROUTE_H_ */
index 8c4387a47542b075e15bdd024bb76905f3f91d7d..dff054212f241bf07012750e647ccae0252afb12 100644 (file)
@@ -548,9 +548,17 @@ route_output(struct mbuf *m, struct socket *so)
                switch (rtm->rtm_type) {
                case RTM_GET: {
                        kauth_cred_t cred;
+                       kauth_cred_t* credp;
                        struct ifaddr *ifa2;
 report:
                        cred = kauth_cred_proc_ref(current_proc());
+
+                       if (rt->rt_ifp == lo_ifp ||
+                           route_op_entitlement_check(so, NULL, ROUTE_OP_READ, TRUE) != 0)
+                               credp = &cred;
+                       else
+                               credp = NULL;
+
                        ifa2 = NULL;
                        RT_LOCK_ASSERT_HELD(rt);
                        info.rti_info[RTAX_DST] = rt_key(rt);
@@ -579,7 +587,7 @@ report:
                        }
                        if (ifa2 != NULL)
                                IFA_LOCK(ifa2);
-                       len = rt_msg2(rtm->rtm_type, &info, NULL, NULL, &cred);
+                       len = rt_msg2(rtm->rtm_type, &info, NULL, NULL, credp);
                        if (ifa2 != NULL)
                                IFA_UNLOCK(ifa2);
                        struct rt_msghdr *out_rtm;
@@ -674,7 +682,6 @@ report:
                }
                RT_UNLOCK(rt);
                break;
-
        default:
                senderr(EOPNOTSUPP);
        }
@@ -1512,8 +1519,14 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
        int error = 0, size;
        struct rt_addrinfo info;
        kauth_cred_t cred;
+       kauth_cred_t *credp;
 
        cred = kauth_cred_proc_ref(current_proc());
+       if (rt->rt_ifp == lo_ifp ||
+           route_op_entitlement_check(NULL, cred, ROUTE_OP_READ, TRUE) != 0)
+               credp = &cred;
+       else
+               credp = NULL;
 
        RT_LOCK(rt);
        if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
@@ -1525,7 +1538,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
        info.rti_info[RTAX_GENMASK] = rt->rt_genmask;
 
        if (w->w_op != NET_RT_DUMP2) {
-               size = rt_msg2(RTM_GET, &info, NULL, w, &cred);
+               size = rt_msg2(RTM_GET, &info, NULL, w, credp);
                if (w->w_req != NULL && w->w_tmem != NULL) {
                        struct rt_msghdr *rtm =
                            (struct rt_msghdr *)(void *)w->w_tmem;
@@ -1541,7 +1554,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
                        error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);
                }
        } else {
-               size = rt_msg2(RTM_GET2, &info, NULL, w, &cred);
+               size = rt_msg2(RTM_GET2, &info, NULL, w, credp);
                if (w->w_req != NULL && w->w_tmem != NULL) {
                        struct rt_msghdr2 *rtm =
                            (struct rt_msghdr2 *)(void *)w->w_tmem;
index 3454404636292dfadb0f9908c04a9976b5799b36..86a2b9920fa0068d64c608457470aaaddce9ed6e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -110,9 +110,13 @@ in_gif_output(
        struct ip iphdr;        /* capsule IP header, host byte ordered */
        int proto, error;
        u_int8_t tos;
-       struct ip_out_args ipoa =
-           { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0, SO_TC_UNSPEC,
-           _NET_SERVICE_TYPE_UNSPEC };
+       struct ip_out_args ipoa;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        GIF_LOCK_ASSERT(sc);
 
index b3ff42cf90b101295b28317ea168d0746afc85c1..b74b0af2f27861df9513c0a72299045396e21843 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -728,8 +728,6 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct proc *p)
 
        if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */
                return (EADDRNOTAVAIL);
-       if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY)
-               return (EINVAL);
        if (!(so->so_options & (SO_REUSEADDR|SO_REUSEPORT)))
                wild = 1;
 
@@ -737,9 +735,14 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct proc *p)
 
        socket_unlock(so, 0); /* keep reference on socket */
        lck_rw_lock_exclusive(pcbinfo->ipi_lock);
+       if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY) {
+               /* another thread completed the bind */
+               lck_rw_done(pcbinfo->ipi_lock);
+               socket_lock(so, 0);
+               return (EINVAL);
+       }
 
        if (nam != NULL) {
-
                if (nam->sa_len != sizeof (struct sockaddr_in)) {
                        lck_rw_done(pcbinfo->ipi_lock);
                        socket_lock(so, 0);
index c67d7663595c93a515dc616342142fe9dc67b1ef..266754acc6814273a0dfc2677bae490743de3da8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2010-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -71,6 +71,7 @@
 
 #include <net/route.h>
 #include <net/if_var.h>
+#include <net/if_ports_used.h>
 #include <net/ntstat.h>
 
 #include <netinet/in.h>
@@ -446,6 +447,10 @@ inpcb_get_ports_used(uint32_t ifindex, int protocol, uint32_t flags,
                    (protocol == PF_INET6 && (inp->inp_vflag & INP_IPV6))))
                        continue;
 
+               if (SOCK_PROTO(inp->inp_socket) != IPPROTO_UDP &&
+                   SOCK_PROTO(inp->inp_socket) != IPPROTO_TCP)
+                       continue;
+
                iswildcard = (((inp->inp_vflag & INP_IPV4) &&
                    inp->inp_laddr.s_addr == INADDR_ANY) ||
                    ((inp->inp_vflag & INP_IPV6) &&
@@ -524,6 +529,8 @@ inpcb_get_ports_used(uint32_t ifindex, int protocol, uint32_t flags,
                if (port == 0)
                        continue;
                bitstr_set(bitfield, port);
+
+               if_ports_used_add_inpcb(ifindex, inp);
        }
        lck_rw_done(pcbinfo->ipi_lock);
 }
index 81595da9b30f11f62ef60f6092b596f2c13cf741..21fc03f44fe5b88fcb6cb3f1ede1e752a12c9d18 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -1463,11 +1463,13 @@ set_netsvctype_dscp_map(size_t in_count,
                        case NET_SERVICE_TYPE_AV:
                        case NET_SERVICE_TYPE_OAM:
                        case NET_SERVICE_TYPE_RD: {
-                               int sotcix;
+                               size_t sotcix;
 
                                sotcix = sotc_index(sotc_by_netservicetype[netsvctype]);
-                               net_qos_dscp_map->sotc_to_dscp[sotcix]  =
-                                   netsvctype_dscp_map[netsvctype].dscp;
+                               if (sotcix != SIZE_T_MAX) {
+                                       net_qos_dscp_map->sotc_to_dscp[sotcix]  =
+                                           netsvctype_dscp_map[netsvctype].dscp;
+                               }
                                break;
                        }
                        case  NET_SERVICE_TYPE_SIG:
@@ -1619,7 +1621,7 @@ set_packet_qos(struct mbuf *m, struct ifnet *ifp, boolean_t qos_allowed,
                 * We still want to prioritize control traffic on the interface
                 * so we do not change the mbuf service class for SO_TC_CTL
                 */
-               if (netsvctype != _NET_SERVICE_TYPE_UNSPEC &&
+               if (IS_VALID_NET_SERVICE_TYPE(netsvctype) &&
                    netsvctype != NET_SERVICE_TYPE_BE) {
                        dscp = default_net_qos_dscp_map.netsvctype_to_dscp[netsvctype];
 
@@ -1630,17 +1632,18 @@ set_packet_qos(struct mbuf *m, struct ifnet *ifp, boolean_t qos_allowed,
                                if (sotc != SO_TC_CTL)
                                        m_set_service_class(m, MBUF_SC_BE);
                        }
-               } else {
+               } else if (sotc != SO_TC_UNSPEC) {
                        size_t sotcix = sotc_index(sotc);
-
-                       dscp = default_net_qos_dscp_map.sotc_to_dscp[sotcix];
-
-                       if (qos_allowed == FALSE && sotc != SO_TC_BE &&
-                           sotc != SO_TC_BK && sotc != SO_TC_BK_SYS &&
-                           sotc != SO_TC_CTL) {
-                               dscp = _DSCP_DF;
-                               if (sotc != SO_TC_CTL)
-                                       m_set_service_class(m, MBUF_SC_BE);
+                       if (sotcix != SIZE_T_MAX) {
+                               dscp = default_net_qos_dscp_map.sotc_to_dscp[sotcix];
+
+                               if (qos_allowed == FALSE && sotc != SO_TC_BE &&
+                                   sotc != SO_TC_BK && sotc != SO_TC_BK_SYS &&
+                                   sotc != SO_TC_CTL) {
+                                       dscp = _DSCP_DF;
+                                       if (sotc != SO_TC_CTL)
+                                               m_set_service_class(m, MBUF_SC_BE);
+                               }
                        }
                }
                if (net_qos_verbose != 0)
index 4981eb25e6012718c29618e76352f675f6420456..74efc18df2d1bf62de3d69b9f15b46d56261fa06 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -374,12 +374,16 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
 
        /* Reinject packet into the system as incoming or outgoing */
        if (!sin || sin->sin_addr.s_addr == 0) {
-               struct ip_out_args ipoa =
-                   { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0, SO_TC_UNSPEC,
-                   _NET_SERVICE_TYPE_UNSPEC };
+               struct ip_out_args ipoa;
                struct route ro;
                struct ip_moptions *imo;
 
+               bzero(&ipoa, sizeof(ipoa));
+               ipoa.ipoa_boundif = IFSCOPE_NONE;
+               ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+               ipoa.ipoa_sotc = SO_TC_UNSPEC;
+               ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
                /*
                 * Don't allow both user specified and setsockopt options,
                 * and don't allow packet length sizes that will crash
index ab1b0452e1efbdf8d588da1e6cb294589674576d..e67b329cabd5902d00d05268cfa629b0df3690b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -263,7 +263,13 @@ icmp_error(
                    (n = m_pullup(n, (oiphlen + sizeof(struct tcphdr)))) == NULL)
                        goto freeit;
 
+               /*
+                * Reinit pointers derived from mbuf data pointer
+                * as things might have moved around with m_pullup
+                */
+               oip = mtod(n, struct ip *);
                th = (struct tcphdr *)(void *)((caddr_t)oip + oiphlen);
+
                if (th != ((struct tcphdr *)P2ROUNDDOWN(th,
                    sizeof(u_int32_t))))
                        goto freeit;
@@ -278,6 +284,13 @@ icmp_error(
                    (n = m_pullup(n, (oiphlen + tcphlen))) == NULL)
                        goto freeit;
 
+               /*
+                * Reinit pointers derived from mbuf data pointer
+                * as things might have moved around with m_pullup
+                */
+               oip = mtod(n, struct ip *);
+               th = (struct tcphdr *)(void *)((caddr_t)oip + oiphlen);
+
                icmpelen = max(tcphlen, min(icmp_datalen,
                    (oip->ip_len - oiphlen)));
        } else
@@ -919,9 +932,13 @@ icmp_send(struct mbuf *m, struct mbuf *opts)
        int hlen;
        struct icmp *icp;
        struct route ro;
-       struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 },
-           IPOAF_SELECT_SRCIF | IPOAF_BOUND_SRCADDR, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip_out_args ipoa;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF | IPOAF_BOUND_SRCADDR;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        if (!(m->m_pkthdr.pkt_flags & PKTF_LOOP) && m->m_pkthdr.rcvif != NULL) {
                ipoa.ipoa_boundif = m->m_pkthdr.rcvif->if_index;
index 1298ab28eb73dc83b6673e5a14902fa38a5be146..97750ef575f648f2736c2d774626e66497b592ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -3835,9 +3835,14 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop)
        n_long dest;
        struct in_addr pkt_dst;
        u_int32_t nextmtu = 0, len;
-       struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 }, 0, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip_out_args ipoa;
        struct ifnet *rcvifp = m->m_pkthdr.rcvif;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
 #if IPSEC
        struct secpolicy *sp = NULL;
        int ipsecerror;
index 2186c63bac1339ca66b80abc7b0f3474e7d05562..ea54abae4069b899d0396c033c9f6fc02c379669 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -333,8 +333,12 @@ ipf_injectv4_out(mbuf_t data, ipfilter_t filter_ref, ipf_pktopts_t options)
        errno_t error = 0;
        struct m_tag *mtag = NULL;
        struct ip_moptions *imo = NULL;
-       struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 }, 0, 0,
-               SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip_out_args ipoa;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        /* Make the IP header contiguous in the mbuf */
        if ((size_t)m->m_len < sizeof (struct ip)) {
@@ -410,8 +414,12 @@ ipf_injectv6_out(mbuf_t data, ipfilter_t filter_ref, ipf_pktopts_t options)
        errno_t error = 0;
        struct m_tag *mtag = NULL;
        struct ip6_moptions *im6o = NULL;
-       struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 }, 0, 0,
-               SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip6_out_args ip6oa;
+
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = IFSCOPE_NONE;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        /* Make the IP header contiguous in the mbuf */
        if ((size_t)m->m_len < sizeof(struct ip6_hdr)) {
index 288f29c717b91a1d143cc4a6ee7ea64cd4b51223..254e2a167d5dfab82e2275f873e7ce7ce353b3b4 100644 (file)
@@ -335,7 +335,7 @@ mp_getsockaddr(struct socket *mp_so, struct sockaddr **nam)
 
        if (mpte->mpte_src.sa_family == AF_INET || mpte->mpte_src.sa_family == 0)
                return mp_getaddr_v4(mp_so, nam, false);
-       else if (mpte->mpte_src.sa_family == AF_INET)
+       else if (mpte->mpte_src.sa_family == AF_INET6)
                return mp_getaddr_v6(mp_so, nam, false);
        else
                return (EINVAL);
@@ -348,7 +348,7 @@ mp_getpeeraddr(struct socket *mp_so, struct sockaddr **nam)
 
        if (mpte->mpte_src.sa_family == AF_INET || mpte->mpte_src.sa_family == 0)
                return mp_getaddr_v4(mp_so, nam, true);
-       else if (mpte->mpte_src.sa_family == AF_INET)
+       else if (mpte->mpte_src.sa_family == AF_INET6)
                return mp_getaddr_v6(mp_so, nam, true);
        else
                return (EINVAL);
index 8cf437f64795a6865b477fe05616ae64599d4743..55829e0a16febfdebe53ca5f8759a8be9a9f8b54 100644 (file)
@@ -383,11 +383,30 @@ mptcp_input(struct mptses *mpte, struct mbuf *m)
 fallback:
                mptcp_sbrcv_grow(mp_tp);
 
-               for (iter = m; iter; iter = iter->m_next) {
+               iter = m;
+               while (iter) {
                        if ((iter->m_flags & M_PKTHDR) &&
                            (iter->m_pkthdr.pkt_flags & PKTF_MPTCP_DFIN)) {
                                mb_dfin = 1;
-                               break;
+                       }
+
+                       if ((iter->m_flags & M_PKTHDR) && m_pktlen(iter) == 0) {
+                               /* Don't add zero-length packets, so jump it! */
+                               if (prev == NULL) {
+                                       m = iter->m_next;
+                                       m_free(iter);
+                                       iter = m;
+                               } else {
+                                       prev->m_next = iter->m_next;
+                                       m_free(iter);
+                                       iter = prev->m_next;
+                               }
+
+                               /* It was a zero-length packet so next one must be a pkthdr */
+                               VERIFY(iter == NULL || iter->m_flags & M_PKTHDR);
+                       } else {
+                               prev = iter;
+                               iter = iter->m_next;
                        }
                }
 
@@ -547,15 +566,15 @@ next:
                sorwakeup(mp_so);
 }
 
-static boolean_t
-mptcp_can_send_more(struct mptcb *mp_tp)
+boolean_t
+mptcp_can_send_more(struct mptcb *mp_tp, boolean_t ignore_reinject)
 {
        struct socket *mp_so = mptetoso(mp_tp->mpt_mpte);
 
        /*
         * Always send if there is data in the reinject-queue.
         */
-       if (mp_tp->mpt_mpte->mpte_reinjectq)
+       if (!ignore_reinject && mp_tp->mpt_mpte->mpte_reinjectq)
                return (TRUE);
 
        /*
@@ -611,7 +630,7 @@ mptcp_output(struct mptses *mpte)
                 MPTCP_SENDER_DBG, MPTCP_LOGLVL_VERBOSE);
 
        old_snd_nxt = mp_tp->mpt_sndnxt;
-       while (mptcp_can_send_more(mp_tp)) {
+       while (mptcp_can_send_more(mp_tp, FALSE)) {
                /* get the "best" subflow to be used for transmission */
                mpts = mptcp_get_subflow(mpte, NULL, &preferred_mpts);
                if (mpts == NULL) {
@@ -667,9 +686,10 @@ mptcp_output(struct mptses *mpte)
                        mpts->mpts_flags |= MPTSF_FAILINGOVER;
                        mpts->mpts_flags &= ~MPTSF_ACTIVE;
                        mpts_tried = mpts;
-                       mptcplog((LOG_ERR, "%s: Error = %d mpts_flags %#x\n", __func__,
-                                 error, mpts->mpts_flags),
-                                MPTCP_SENDER_DBG, MPTCP_LOGLVL_ERR);
+                       if (error != ECANCELED)
+                               mptcplog((LOG_ERR, "%s: Error = %d mpts_flags %#x\n", __func__,
+                                         error, mpts->mpts_flags),
+                                        MPTCP_SENDER_DBG, MPTCP_LOGLVL_ERR);
                        break;
                }
                /* The model is to have only one active flow at a time */
@@ -710,6 +730,12 @@ mptcp_output(struct mptses *mpte)
                }
        }
 
+       if (mp_tp->mpt_state > MPTCPS_CLOSE_WAIT) {
+               if (mp_tp->mpt_sndnxt + 1 == mp_tp->mpt_sndmax &&
+                   mp_tp->mpt_snduna == mp_tp->mpt_sndnxt)
+                       mptcp_finish_usrclosed(mpte);
+       }
+
        mptcp_handle_deferred_upcalls(mpte->mpte_mppcb, MPP_WUPCALL);
 
        /* subflow errors should not be percolated back up */
@@ -1010,7 +1036,7 @@ mptcp_close_fsm(struct mptcb *mp_tp, uint32_t event)
        switch (mp_tp->mpt_state) {
        case MPTCPS_CLOSED:
        case MPTCPS_LISTEN:
-               mp_tp->mpt_state = MPTCPS_CLOSED;
+               mp_tp->mpt_state = MPTCPS_TERMINATE;
                break;
 
        case MPTCPS_ESTABLISHED:
@@ -1226,7 +1252,7 @@ mptcp_input_csum(struct tcpcb *tp, struct mbuf *m, uint64_t dsn, uint32_t sseq,
 uint32_t
 mptcp_output_csum(struct mbuf *m, uint64_t dss_val, uint32_t sseq, uint16_t dlen)
 {
-       u_int32_t sum = 0;
+       uint32_t sum = 0;
 
        if (dlen)
                sum = m_sum16(m, 0, dlen);
@@ -1314,13 +1340,14 @@ mptcp_handle_deferred_upcalls(struct mppcb *mpp, uint32_t flag)
        }
 }
 
-static void
+void
 mptcp_ask_for_nat64(struct ifnet *ifp)
 {
        in6_post_msg(ifp, KEV_INET6_REQUEST_NAT64_PREFIX, NULL, NULL);
 
-       mptcplog((LOG_DEBUG, "%s: asked for NAT64-prefix on %s\n",
-                __func__, ifp->if_name), MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
+       os_log_info(mptcp_log_handle,
+                   "%s: asked for NAT64-prefix on %s\n", __func__,
+                   ifp->if_name);
 }
 
 static void
@@ -1344,11 +1371,6 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
        ifindex = flow->interface_index;
        VERIFY(ifindex != IFSCOPE_NONE);
 
-       /* ToDo - remove after rdar://problem/32007628 */
-       if (!IF_INDEX_IN_RANGE(ifindex))
-               printf("%s 1 ifindex %u not in range of flow %p action %d\n",
-                      __func__, ifindex, flow, action);
-
        /* About to be garbage-collected (see note about MPTCP/NECP interactions) */
        if (mp->mpp_socket->so_usecount == 0)
                return;
@@ -1362,12 +1384,13 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
                        goto out;
        }
 
+       mpte_lock_assert_held(mpte);
+
        mp_tp = mpte->mpte_mptcb;
        mp_so = mptetoso(mpte);
 
-       mptcplog((LOG_DEBUG, "%s, action: %u ifindex %u usecount %u mpt_flags %#x state %u\n",
-                __func__, action, ifindex, mp->mpp_socket->so_usecount, mp_tp->mpt_flags, mp_tp->mpt_state),
-                MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
+       os_log_debug(mptcp_log_handle, "%s, action: %u ifindex %u usecount %u mpt_flags %#x state %u\n",
+                    __func__, action, ifindex, mp->mpp_socket->so_usecount, mp_tp->mpt_flags, mp_tp->mpt_state);
 
        /* No need on fallen back sockets */
        if (mp_tp->mpt_flags & MPTCPF_FALLBACK_TO_TCP)
@@ -1382,23 +1405,15 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
                mptcp_sched_create_subflows(mpte);
        } else if (action == NECP_CLIENT_CBACTION_VIABLE ||
                   action == NECP_CLIENT_CBACTION_INITIAL) {
-               int found_empty = 0, empty_index = -1;
+               int found_slot = 0, slot_index = -1;
+               boolean_t has_v4 = !!(flow->necp_flow_flags & NECP_CLIENT_RESULT_FLAG_HAS_IPV4);
+               boolean_t has_v6 = !!(flow->necp_flow_flags & NECP_CLIENT_RESULT_FLAG_HAS_IPV6);
                struct ifnet *ifp;
 
-               /* ToDo - remove after rdar://problem/32007628 */
-               if (!IF_INDEX_IN_RANGE(ifindex))
-                       printf("%s 2 ifindex %u not in range of flow %p action %d\n",
-                              __func__, ifindex, flow, action);
-
                ifnet_head_lock_shared();
                ifp = ifindex2ifnet[ifindex];
                ifnet_head_done();
 
-               /* ToDo - remove after rdar://problem/32007628 */
-               if (!IF_INDEX_IN_RANGE(ifindex))
-                       printf("%s 3 ifindex %u not in range of flow %p action %d\n",
-                              __func__, ifindex, flow, action);
-
                if (ifp == NULL)
                        goto out;
 
@@ -1410,14 +1425,31 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
                    (mp_so->so_restrictions & SO_RESTRICT_DENY_CELLULAR))
                        goto out;
 
+               /* Look for the slot on where to store/update the interface-info. */
                for (i = 0; i < mpte->mpte_itfinfo_size; i++) {
+                       /* Found a potential empty slot where we can put it */
                        if (mpte->mpte_itfinfo[i].ifindex == 0) {
-                               found_empty = 1;
-                               empty_index = i;
+                               found_slot = 1;
+                               slot_index = i;
+                       }
+
+                       /*
+                        * The interface is already in our array. Check if we
+                        * need to update it.
+                        */
+                       if (mpte->mpte_itfinfo[i].ifindex == ifindex &&
+                           (mpte->mpte_itfinfo[i].has_v4_conn != has_v4 ||
+                            mpte->mpte_itfinfo[i].has_v6_conn != has_v6)) {
+                               found_slot = 1;
+                               slot_index = i;
+                               break;
                        }
 
                        if (mpte->mpte_itfinfo[i].ifindex == ifindex) {
-                               /* Ok, it's already there */
+                               /*
+                                * Ok, it's already there and we don't need
+                                * to update it
+                                */
                                goto out;
                        }
                }
@@ -1429,7 +1461,7 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
                        goto out;
                }
 
-               if (found_empty == 0) {
+               if (found_slot == 0) {
                        int new_size = mpte->mpte_itfinfo_size * 2;
                        struct mpt_itf_info *info = _MALLOC(sizeof(*info) * new_size, M_TEMP, M_ZERO);
 
@@ -1445,7 +1477,7 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
                                _FREE(mpte->mpte_itfinfo, M_TEMP);
 
                        /* We allocated a new one, thus the first must be empty */
-                       empty_index = mpte->mpte_itfinfo_size;
+                       slot_index = mpte->mpte_itfinfo_size;
 
                        mpte->mpte_itfinfo = info;
                        mpte->mpte_itfinfo_size = new_size;
@@ -1454,10 +1486,10 @@ mptcp_session_necp_cb(void *handle, int action, struct necp_client_flow *flow)
                            MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
                }
 
-               VERIFY(empty_index >= 0 && empty_index < (int)mpte->mpte_itfinfo_size);
-               mpte->mpte_itfinfo[empty_index].ifindex = ifindex;
-               mpte->mpte_itfinfo[empty_index].has_v4_conn = !!(flow->necp_flow_flags & NECP_CLIENT_RESULT_FLAG_HAS_IPV4);
-               mpte->mpte_itfinfo[empty_index].has_v6_conn = !!(flow->necp_flow_flags & NECP_CLIENT_RESULT_FLAG_HAS_IPV6);
+               VERIFY(slot_index >= 0 && slot_index < (int)mpte->mpte_itfinfo_size);
+               mpte->mpte_itfinfo[slot_index].ifindex = ifindex;
+               mpte->mpte_itfinfo[slot_index].has_v4_conn = has_v4;
+               mpte->mpte_itfinfo[slot_index].has_v6_conn = has_v6;
 
                mptcp_sched_create_subflows(mpte);
        }
index 40007851af41d3cf77522ce00f27dc707479c9ff..6da8235e881cbc45b21deb24fcebef86f58020cf 100644 (file)
@@ -459,6 +459,8 @@ mptcp_setup_opts(struct tcpcb *tp, int32_t off, u_char *opt,
        if (sndfin) {                                                   \
                dsn_opt.mdss_copt.mdss_flags |= MDSS_F;                 \
                dsn_opt.mdss_data_len += 1;                             \
+               if (do_csum)                                            \
+                       dss_csum = in_addword(dss_csum, 1);             \
        }                                                               \
 }
 
@@ -755,12 +757,24 @@ do_ack64_only:
        }
 
        if (tp->t_mpflags & TMPF_SEND_DFIN) {
+               unsigned int dssoptlen = sizeof(struct mptcp_dss_ack_opt);
                struct mptcp_dss_ack_opt dss_ack_opt;
-               unsigned int dssoptlen = sizeof (struct mptcp_dss_ack_opt);
+               uint16_t dss_csum;
+
+               if (do_csum) {
+                       uint64_t dss_val = mptcp_hton64(mp_tp->mpt_sndmax - 1);
+                       uint16_t dlen = htons(1);
+                       uint32_t sseq = 0;
+                       uint32_t sum;
+
 
-               if (do_csum)
                        dssoptlen += 2;
 
+                       sum = in_pseudo64(dss_val, sseq, dlen);
+                       ADDCARRY(sum);
+                       dss_csum = ~sum & 0xffff;
+               }
+
                CHECK_OPTLEN;
 
                bzero(&dss_ack_opt, sizeof (dss_ack_opt));
@@ -769,7 +783,7 @@ do_ack64_only:
                 * Data FIN occupies one sequence space.
                 * Don't send it if it has been Acked.
                 */
-               if (((mp_tp->mpt_sndnxt + 1) != mp_tp->mpt_sndmax) ||
+               if ((mp_tp->mpt_sndnxt + 1 != mp_tp->mpt_sndmax) ||
                    (mp_tp->mpt_snduna == mp_tp->mpt_sndmax))
                        goto ret_optlen;
 
@@ -780,11 +794,14 @@ do_ack64_only:
                dss_ack_opt.mdss_ack =
                    htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
                dss_ack_opt.mdss_dsn =
-                   htonl(MPTCP_DATASEQ_LOW32(mp_tp->mpt_sndnxt));
+                   htonl(MPTCP_DATASEQ_LOW32(mp_tp->mpt_sndmax - 1));
                dss_ack_opt.mdss_subflow_seqn = 0;
                dss_ack_opt.mdss_data_len = 1;
                dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
                memcpy(opt + optlen, &dss_ack_opt, sizeof (dss_ack_opt));
+               if (do_csum)
+                       *((uint16_t *)(void *)(opt + optlen + sizeof (dss_ack_opt))) = dss_csum;
+
                optlen += dssoptlen;
        }
 
@@ -937,7 +954,6 @@ mptcp_do_mpcapable_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
        }
        tcp_heuristic_mptcp_success(tp);
        tp->t_mpflags |= (TMPF_SND_KEYS | TMPF_MPTCP_TRUE);
-       tp->t_inpcb->inp_socket->so_flags |= SOF_MPTCP_TRUE;
 }
 
 
@@ -1021,9 +1037,7 @@ mptcp_validate_join_hmac(struct tcpcb *tp, u_char* hmac, int mac_len)
 void
 mptcp_data_ack_rcvd(struct mptcb *mp_tp, struct tcpcb *tp, u_int64_t full_dack)
 {
-       u_int64_t acked = 0;
-
-       acked = full_dack - mp_tp->mpt_snduna;
+       u_int64_t acked = full_dack - mp_tp->mpt_snduna;
 
        if (acked) {
                struct socket *mp_so = mptetoso(mp_tp->mpt_mpte);
index 590fa2c465855603654fbc249900f1f7e31cfaa4..a4a61beb26c96f8012f47763df375ad88a9d14a3 100644 (file)
@@ -189,6 +189,11 @@ SYSCTL_INT(_net_inet_mptcp, OID_AUTO, dbg_level, CTLFLAG_RW | CTLFLAG_LOCKED,
 SYSCTL_UINT(_net_inet_mptcp, OID_AUTO, pcbcount, CTLFLAG_RD|CTLFLAG_LOCKED,
        &mtcbinfo.mppi_count, 0, "Number of active PCBs");
 
+
+static int mptcp_alternate_port = 0;
+SYSCTL_INT(_net_inet_mptcp, OID_AUTO, alternate_port, CTLFLAG_RW | CTLFLAG_LOCKED,
+          &mptcp_alternate_port, 0, "Set alternate port for MPTCP connections");
+
 static struct protosw mptcp_subflow_protosw;
 static struct pr_usrreqs mptcp_subflow_usrreqs;
 #if INET6
@@ -270,6 +275,8 @@ static mptsub_ev_entry_t mpsub_ev_entry_tbl [] = {
        },
 };
 
+os_log_t mptcp_log_handle;
+
 /*
  * Protocol pr_init callback.
  */
@@ -392,6 +399,8 @@ mptcp_init(struct protosw *pp, struct domain *dp)
        zone_change(mpt_subauth_zone, Z_EXPAND, TRUE);
 
        mptcp_last_cellicon_set = tcp_now;
+
+       mptcp_log_handle = os_log_create("com.apple.xnu.net.mptcp", "mptcp");
 }
 
 int
@@ -490,6 +499,9 @@ mptcp_sescreate(struct mppcb *mpp)
        mpte->mpte_itfinfo = &mpte->_mpte_itfinfo[0];
        mpte->mpte_itfinfo_size = MPTE_ITFINFO_SIZE;
 
+       if (mptcp_alternate_port)
+               mpte->mpte_alternate_port = htons(mptcp_alternate_port);
+
        /* MPTCP Protocol Control Block */
        bzero(mp_tp, sizeof (*mp_tp));
        mp_tp->mpt_mpte = mpte;
@@ -743,9 +755,9 @@ mptcp_synthesize_nat64(struct in6_addr *addr, uint32_t len, struct in_addr *addr
                        panic("NAT64-prefix len is wrong: %u\n", len);
        }
 
-       mptcplog((LOG_DEBUG, "%s: nat64prefix-len %u synthesized %s\n", __func__,
-                 len, inet_ntop(AF_INET6, (void *)addr, buf, sizeof(buf))),
-                MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
+       os_log_info(mptcp_log_handle, "%s: nat64prefix-len %u synthesized %s\n",
+                   __func__, len,
+                   inet_ntop(AF_INET6, (void *)addr, buf, sizeof(buf)));
 
        return (0);
 }
@@ -781,7 +793,8 @@ mptcp_check_subflows_and_add(struct mptses *mpte)
                                continue;
 
                        if (ifp->if_index == ifindex &&
-                           !(mpts->mpts_socket->so_state & SS_ISDISCONNECTED)) {
+                           !(mpts->mpts_socket->so_state & SS_ISDISCONNECTED) &&
+                           sototcpcb(mpts->mpts_socket)->t_state != TCPS_CLOSED) {
                                /*
                                 * We found a subflow on this interface.
                                 * No need to create a new one.
@@ -881,6 +894,17 @@ mptcp_check_subflows_and_add(struct mptses *mpte)
                                dst = (struct sockaddr *)&nat64pre;
                        }
 
+                       /* Initial subflow started on a NAT64'd address? */
+                       if (mpte->mpte_dst.sa_family == AF_INET6 &&
+                           mpte->mpte_dst_v4_nat64.sin_family == AF_INET) {
+                               dst = (struct sockaddr *)&mpte->mpte_dst_v4_nat64;
+                       }
+
+                       if (dst->sa_family == AF_INET && !info->has_v4_conn)
+                               continue;
+                       if (dst->sa_family == AF_INET6 && !info->has_v6_conn)
+                               continue;
+
                        mptcp_subflow_add(mpte, NULL, dst, ifindex, NULL);
                }
        }
@@ -1525,12 +1549,29 @@ mptcp_subflow_soconnectx(struct mptses *mpte, struct mptsub *mpts)
        struct mptcb *mp_tp;
        struct sockaddr *dst;
        struct proc *p;
-       int af, error;
-
-       mpte_lock_assert_held(mpte);    /* same as MP socket lock */
+       int af, error, dport;
 
        mp_so = mptetoso(mpte);
        mp_tp = mpte->mpte_mptcb;
+       so = mpts->mpts_socket;
+       af = mpts->mpts_dst.sa_family;
+       dst = &mpts->mpts_dst;
+
+       VERIFY((mpts->mpts_flags & (MPTSF_CONNECTING|MPTSF_CONNECTED)) == MPTSF_CONNECTING);
+       VERIFY(mpts->mpts_socket != NULL);
+       VERIFY(af == AF_INET || af == AF_INET6);
+
+       if (af == AF_INET) {
+               inet_ntop(af, &SIN(dst)->sin_addr.s_addr, dbuf, sizeof (dbuf));
+               dport = ntohs(SIN(dst)->sin_port);
+       } else {
+               inet_ntop(af, &SIN6(dst)->sin6_addr, dbuf, sizeof (dbuf));
+               dport = ntohs(SIN6(dst)->sin6_port);
+       }
+
+       os_log_info(mptcp_log_handle,
+                   "%s: ifindex %u dst %s:%d pended %u\n", __func__, mpts->mpts_ifscope,
+                   dbuf, dport, !!(mpts->mpts_flags & MPTSF_CONNECT_PENDING));
 
        p = proc_find(mp_so->last_pid);
        if (p == PROC_NULL) {
@@ -1540,24 +1581,6 @@ mptcp_subflow_soconnectx(struct mptses *mpte, struct mptsub *mpts)
                return (ESRCH);
        }
 
-       so = mpts->mpts_socket;
-       af = mpts->mpts_dst.sa_family;
-
-       VERIFY((mpts->mpts_flags & (MPTSF_CONNECTING|MPTSF_CONNECTED)) == MPTSF_CONNECTING);
-       VERIFY(mpts->mpts_socket != NULL);
-       VERIFY(af == AF_INET || af == AF_INET6);
-
-       dst = &mpts->mpts_dst;
-       mptcplog((LOG_DEBUG, "%s: connectx mp_so 0x%llx dst %s[%d] cid %d [pended %s]\n",
-                 __func__, (u_int64_t)VM_KERNEL_ADDRPERM(mp_so),
-                 inet_ntop(af, ((af == AF_INET) ? (void *)&SIN(dst)->sin_addr.s_addr :
-                                (void *)&SIN6(dst)->sin6_addr),
-                                dbuf, sizeof (dbuf)),
-                 ((af == AF_INET) ? ntohs(SIN(dst)->sin_port) : ntohs(SIN6(dst)->sin6_port)),
-                 mpts->mpts_connid,
-                 ((mpts->mpts_flags & MPTSF_CONNECT_PENDING) ? "YES" : "NO")),
-                MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
-
        mpts->mpts_flags &= ~MPTSF_CONNECT_PENDING;
 
        mptcp_attach_to_subf(so, mpte->mpte_mptcb, mpte->mpte_addrid_last);
@@ -2243,7 +2266,7 @@ mptcp_subflow_disconnect(struct mptses *mpte, struct mptsub *mpts)
 
        if (!(so->so_state & (SS_ISDISCONNECTING | SS_ISDISCONNECTED)) &&
            (so->so_state & SS_ISCONNECTED)) {
-               mptcplog((LOG_DEBUG, "MPTCP Socket %s: cid %d fin %d\n",
+               mptcplog((LOG_DEBUG, "%s: cid %d fin %d\n",
                    __func__, mpts->mpts_connid, send_dfin),
                    MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
 
@@ -2400,6 +2423,27 @@ mptcp_subflow_wupcall(struct socket *so, void *arg, int waitf)
        mptcp_output(mpte);
 }
 
+static boolean_t
+mptcp_search_seq_in_sub(struct mbuf *m, struct socket *so)
+{
+       struct mbuf *so_m = so->so_snd.sb_mb;
+       uint64_t dsn = m->m_pkthdr.mp_dsn;
+
+       while (so_m) {
+               VERIFY(so_m->m_flags & M_PKTHDR);
+               VERIFY(so_m->m_pkthdr.pkt_flags & PKTF_MPTCP);
+
+               /* Part of the segment is covered, don't reinject here */
+               if (so_m->m_pkthdr.mp_dsn <= dsn &&
+                   so_m->m_pkthdr.mp_dsn + so_m->m_pkthdr.mp_rlen > dsn)
+                       return TRUE;
+
+               so_m = so_m->m_next;
+       }
+
+       return FALSE;
+}
+
 /*
  * Subflow socket output.
  *
@@ -2467,9 +2511,14 @@ mptcp_subflow_output(struct mptses *mpte, struct mptsub *mpts, int flags)
                sb_mb = mp_so->so_snd.sb_mb;
 
        if (sb_mb == NULL) {
-               mptcplog((LOG_ERR, "%s: No data in MPTCP-sendbuffer! smax %u snxt %u suna %u\n",
-                         __func__, (uint32_t)mp_tp->mpt_sndmax, (uint32_t)mp_tp->mpt_sndnxt, (uint32_t)mp_tp->mpt_snduna),
+               mptcplog((LOG_ERR, "%s: No data in MPTCP-sendbuffer! smax %u snxt %u suna %u state %u flags %#x\n",
+                         __func__, (uint32_t)mp_tp->mpt_sndmax, (uint32_t)mp_tp->mpt_sndnxt,
+                         (uint32_t)mp_tp->mpt_snduna, mp_tp->mpt_state, mp_so->so_flags1),
                         MPTCP_SENDER_DBG, MPTCP_LOGLVL_ERR);
+
+               /* Fix it to prevent looping */
+               if (MPTCP_SEQ_LT(mp_tp->mpt_sndnxt, mp_tp->mpt_snduna))
+                       mp_tp->mpt_sndnxt = mp_tp->mpt_snduna;
                goto out;
        }
 
@@ -2545,6 +2594,7 @@ mptcp_subflow_output(struct mptses *mpte, struct mptsub *mpts, int flags)
        if (mpte->mpte_reinjectq)
                sb_mb = mpte->mpte_reinjectq;
        else
+dont_reinject:
                sb_mb = mp_so->so_snd.sb_mb;
        if (sb_mb == NULL) {
                mptcplog((LOG_ERR, "%s send-buffer is still empty\n", __func__),
@@ -2552,8 +2602,20 @@ mptcp_subflow_output(struct mptses *mpte, struct mptsub *mpts, int flags)
                goto out;
        }
 
-       if (mpte->mpte_reinjectq) {
+       if (sb_mb == mpte->mpte_reinjectq) {
                sb_cc = sb_mb->m_pkthdr.mp_rlen;
+               off = 0;
+
+               if (mptcp_search_seq_in_sub(sb_mb, so)) {
+                       if (mptcp_can_send_more(mp_tp, TRUE)) {
+                               goto dont_reinject;
+                       }
+
+                       error = ECANCELED;
+                       goto out;
+               }
+
+               reinjected = TRUE;
        } else if (flags & MPTCP_SUBOUT_PROBING) {
                sb_cc = sb_mb->m_pkthdr.mp_rlen;
                off = 0;
@@ -2593,13 +2655,13 @@ mptcp_subflow_output(struct mptses *mpte, struct mptsub *mpts, int flags)
         * Create a DSN mapping for the data we are about to send. It all
         * has the same mapping.
         */
-       if (mpte->mpte_reinjectq)
+       if (reinjected)
                mpt_dsn = sb_mb->m_pkthdr.mp_dsn;
        else
                mpt_dsn = mp_tp->mpt_snduna + off;
 
        mpt_mbuf = sb_mb;
-       while (mpt_mbuf && mpte->mpte_reinjectq == NULL &&
+       while (mpt_mbuf && reinjected == FALSE &&
               (mpt_mbuf->m_pkthdr.mp_rlen == 0 ||
                mpt_mbuf->m_pkthdr.mp_rlen <= (uint32_t)off)) {
                off -= mpt_mbuf->m_pkthdr.mp_rlen;
@@ -2665,9 +2727,7 @@ next:
                mpt_mbuf = mpt_mbuf->m_next;
        }
 
-       if (mpte->mpte_reinjectq) {
-               reinjected = TRUE;
-
+       if (reinjected) {
                if (sb_cc < sb_mb->m_pkthdr.mp_rlen) {
                        struct mbuf *n = sb_mb;
 
@@ -3022,7 +3082,7 @@ mptcp_clean_reinjectq(struct mptses *mpte)
                struct mbuf *m = mpte->mpte_reinjectq;
 
                if (MPTCP_SEQ_GEQ(m->m_pkthdr.mp_dsn, mp_tp->mpt_snduna) ||
-                   MPTCP_SEQ_GEQ(m->m_pkthdr.mp_dsn + m->m_pkthdr.mp_rlen, mp_tp->mpt_snduna))
+                   MPTCP_SEQ_GT(m->m_pkthdr.mp_dsn + m->m_pkthdr.mp_rlen, mp_tp->mpt_snduna))
                        break;
 
                mpte->mpte_reinjectq = m->m_nextpkt;
@@ -3318,6 +3378,89 @@ mptcp_subflow_ifdenied_ev(struct mptses *mpte, struct mptsub *mpts,
        return (MPTS_EVRET_DELETE);
 }
 
+/*
+ * https://tools.ietf.org/html/rfc6052#section-2
+ * https://tools.ietf.org/html/rfc6147#section-5.2
+ */
+static boolean_t
+mptcp_desynthesize_ipv6_addr(const struct in6_addr *addr,
+                            const struct ipv6_prefix *prefix,
+                            struct in_addr *addrv4)
+{
+       char buf[MAX_IPv4_STR_LEN];
+       char *ptrv4 = (char *)addrv4;
+       const char *ptr = (const char *)addr;
+
+       if (memcmp(addr, &prefix->ipv6_prefix, prefix->prefix_len) != 0)
+               return false;
+
+       switch (prefix->prefix_len) {
+               case NAT64_PREFIX_LEN_96:
+                       memcpy(ptrv4, ptr + 12, 4);
+                       break;
+               case NAT64_PREFIX_LEN_64:
+                       memcpy(ptrv4, ptr + 9, 4);
+                       break;
+               case NAT64_PREFIX_LEN_56:
+                       memcpy(ptrv4, ptr + 7, 1);
+                       memcpy(ptrv4 + 1, ptr + 9, 3);
+                       break;
+               case NAT64_PREFIX_LEN_48:
+                       memcpy(ptrv4, ptr + 6, 2);
+                       memcpy(ptrv4 + 2, ptr + 9, 2);
+                       break;
+               case NAT64_PREFIX_LEN_40:
+                       memcpy(ptrv4, ptr + 5, 3);
+                       memcpy(ptrv4 + 3, ptr + 9, 1);
+                       break;
+               case NAT64_PREFIX_LEN_32:
+                       memcpy(ptrv4, ptr + 4, 4);
+                       break;
+               default:
+                       panic("NAT64-prefix len is wrong: %u\n",
+                             prefix->prefix_len);
+       }
+
+       os_log_info(mptcp_log_handle, "%s desynthesized to %s\n", __func__,
+                   inet_ntop(AF_INET, (void *)addrv4, buf, sizeof(buf)));
+
+       return true;
+}
+
+static void
+mptcp_handle_ipv6_connection(struct mptses *mpte, const struct mptsub *mpts)
+{
+       struct ipv6_prefix nat64prefixes[NAT64_MAX_NUM_PREFIXES];
+       struct socket *so = mpts->mpts_socket;
+       struct ifnet *ifp;
+       int j;
+
+       ifp = sotoinpcb(so)->inp_last_outifp;
+
+       if (ifnet_get_nat64prefix(ifp, nat64prefixes) == ENOENT) {
+               mptcp_ask_for_nat64(ifp);
+               return;
+       }
+
+
+       for (j = 0; j < NAT64_MAX_NUM_PREFIXES; j++) {
+               int success;
+
+               if (nat64prefixes[j].prefix_len == 0)
+                       continue;
+
+               success = mptcp_desynthesize_ipv6_addr(&mpte->__mpte_dst_v6.sin6_addr,
+                                                      &nat64prefixes[j],
+                                                      &mpte->mpte_dst_v4_nat64.sin_addr);
+               if (success) {
+                       mpte->mpte_dst_v4_nat64.sin_len = sizeof(mpte->mpte_dst_v4_nat64);
+                       mpte->mpte_dst_v4_nat64.sin_family = AF_INET;
+                       mpte->mpte_dst_v4_nat64.sin_port = mpte->__mpte_dst_v6.sin6_port;
+                       break;
+               }
+       }
+}
+
 /*
  * Handle SO_FILT_HINT_CONNECTED subflow socket event.
  */
@@ -3422,6 +3565,8 @@ mptcp_subflow_connected_ev(struct mptses *mpte, struct mptsub *mpts,
                        in6_getsockaddr_s(so, &mpte->__mpte_src_v6);
                }
 
+               mpts->mpts_flags |= MPTSF_ACTIVE;
+
                /* case (a) above */
                if (!mpok) {
                        tcpstat.tcps_mpcap_fallback++;
@@ -3435,11 +3580,12 @@ mptcp_subflow_connected_ev(struct mptses *mpte, struct mptsub *mpts,
                        } else {
                                mpts->mpts_flags |= MPTSF_PREFERRED;
                        }
-                       mpts->mpts_flags |= MPTSF_ACTIVE;
-
                        mpts->mpts_flags |= MPTSF_MPCAP_CTRSET;
                        mpte->mpte_nummpcapflows++;
 
+                       if (SOCK_DOM(so) == AF_INET6)
+                               mptcp_handle_ipv6_connection(mpte, mpts);
+
                        mptcp_check_subflows_and_add(mpte);
 
                        if (IFNET_IS_CELLULAR(inp->inp_last_outifp))
@@ -3482,13 +3628,26 @@ mptcp_subflow_connected_ev(struct mptses *mpte, struct mptsub *mpts,
        } else {
                unsigned int i;
 
-               /* Mark this interface as non-MPTCP */
-               for (i = 0; i < mpte->mpte_itfinfo_size; i++) {
-                       struct mpt_itf_info *info =  &mpte->mpte_itfinfo[i];
+               /* Should we try the alternate port? */
+               if (mpte->mpte_alternate_port &&
+                   inp->inp_fport != mpte->mpte_alternate_port) {
+                       union sockaddr_in_4_6 dst;
+                       struct sockaddr_in *dst_in = (struct sockaddr_in *)&dst;
 
-                       if (inp->inp_last_outifp->if_index == info->ifindex) {
-                               info->no_mptcp_support = 1;
-                               break;
+                       memcpy(&dst, &mpts->mpts_dst, mpts->mpts_dst.sa_len);
+
+                       dst_in->sin_port = mpte->mpte_alternate_port;
+
+                       mptcp_subflow_add(mpte, NULL, (struct sockaddr *)&dst,
+                                         mpts->mpts_ifscope , NULL);
+               } else { /* Else, we tried all we could, mark this interface as non-MPTCP */
+                       for (i = 0; i < mpte->mpte_itfinfo_size; i++) {
+                               struct mpt_itf_info *info =  &mpte->mpte_itfinfo[i];
+
+                               if (inp->inp_last_outifp->if_index == info->ifindex) {
+                                       info->no_mptcp_support = 1;
+                                       break;
+                               }
                        }
                }
 
index 0f427e1842efdc890cc56a70873574b6577e6715..969ceddf8d692e38cf6634f96a995db7ee8442a9 100644 (file)
@@ -82,8 +82,7 @@ mptcp_timer_demux(struct mptses *mpte, uint32_t now_msecs)
                        break;
                if ((now_msecs - mp_tp->mpt_rxtstart) >
                    (mptcp_rto*hz)) {
-                       if (MPTCP_SEQ_GT(mp_tp->mpt_snduna,
-                           mp_tp->mpt_rtseq)) {
+                       if (MPTCP_SEQ_GT(mp_tp->mpt_snduna, mp_tp->mpt_rtseq)) {
                                mp_tp->mpt_timer_vals = 0;
                                mp_tp->mpt_rtseq = 0;
                                break;
@@ -94,10 +93,10 @@ mptcp_timer_demux(struct mptses *mpte, uint32_t now_msecs)
                                DTRACE_MPTCP1(error, struct mptcb *, mp_tp);
                        } else {
                                mp_tp->mpt_sndnxt = mp_tp->mpt_rtseq;
-                               mptcplog((LOG_DEBUG, "MPTCP Socket: "
-                                  "%s: REXMT %d times.\n",
-                                   __func__, mp_tp->mpt_rxtshift),
-                                   MPTCP_SOCKET_DBG, MPTCP_LOGLVL_LOG);
+                               os_log_info(mptcp_log_handle,
+                                           "%s: REXMT %d sndnxt %u\n",
+                                           __func__, mp_tp->mpt_rxtshift,
+                                           (uint32_t)mp_tp->mpt_sndnxt);
                                mptcp_output(mpte);
                        }
                } else {
index fb199c658fe739a69b4a1a04ca6b7c58ae41d07c..8749d1a0a40e5e9fa195f57e42970ac88d2310d6 100644 (file)
@@ -693,8 +693,7 @@ mptcp_disconnect(struct mptses *mpte)
        mp_so = mptetoso(mpte);
        mp_tp = mpte->mpte_mptcb;
 
-       mptcplog((LOG_DEBUG, "MPTCP Socket: "
-           "%s: mp_so 0x%llx %d\n", __func__,
+       mptcplog((LOG_DEBUG, "%s: mp_so 0x%llx %d\n", __func__,
            (u_int64_t)VM_KERNEL_ADDRPERM(mp_so), mp_so->so_error),
            MPTCP_SOCKET_DBG, MPTCP_LOGLVL_LOG);
 
@@ -758,27 +757,19 @@ mptcp_usr_disconnectx(struct socket *mp_so, sae_associd_t aid, sae_connid_t cid)
        return (mptcp_usr_disconnect(mp_so));
 }
 
-/*
- * User issued close, and wish to trail thru shutdown states.
- */
-static struct mptses *
-mptcp_usrclosed(struct mptses *mpte)
+void
+mptcp_finish_usrclosed(struct mptses *mpte)
 {
-       struct socket *mp_so;
-       struct mptcb *mp_tp;
-       struct mptsub *mpts;
-
-       mpte_lock_assert_held(mpte);    /* same as MP socket lock */
-       mp_so = mptetoso(mpte);
-       mp_tp = mpte->mpte_mptcb;
-
-       mptcp_close_fsm(mp_tp, MPCE_CLOSE);
+       struct mptcb *mp_tp = mpte->mpte_mptcb;
+       struct socket *mp_so = mptetoso(mpte);
 
        if (mp_tp->mpt_state == MPTCPS_CLOSED) {
                mpte = mptcp_close(mpte, mp_tp);
        } else if (mp_tp->mpt_state >= MPTCPS_FIN_WAIT_2) {
                soisdisconnected(mp_so);
        } else {
+               struct mptsub *mpts;
+
                TAILQ_FOREACH(mpts, &mpte->mpte_subflows, mpts_entry) {
                        if ((mp_so->so_state & (SS_CANTRCVMORE|SS_CANTSENDMORE)) ==
                            (SS_CANTRCVMORE | SS_CANTSENDMORE))
@@ -787,6 +778,23 @@ mptcp_usrclosed(struct mptses *mpte)
                                mptcp_subflow_shutdown(mpte, mpts);
                }
        }
+}
+
+/*
+ * User issued close, and wish to trail thru shutdown states.
+ */
+static struct mptses *
+mptcp_usrclosed(struct mptses *mpte)
+{
+       struct mptcb *mp_tp = mpte->mpte_mptcb;
+
+       mptcp_close_fsm(mp_tp, MPCE_CLOSE);
+
+       /* Not everything has been acknowledged - don't close the subflows! */
+       if (mp_tp->mpt_sndnxt + 1 != mp_tp->mpt_sndmax)
+               return (mpte);
+
+       mptcp_finish_usrclosed(mpte);
 
        return (mpte);
 }
@@ -1457,6 +1465,21 @@ mptcp_setopt(struct mptses *mpte, struct sockopt *sopt)
 
                        mpte->mpte_flags |= MPTE_SVCTYPE_CHECKED;
 
+                       goto out;
+               case MPTCP_ALTERNATE_PORT:
+                       /* record at MPTCP level */
+                       error = sooptcopyin(sopt, &optval, sizeof(optval),
+                           sizeof(optval));
+                       if (error)
+                               goto out;
+
+                       if (optval < 0 || optval > UINT16_MAX) {
+                               error = EINVAL;
+                               goto out;
+                       }
+
+                       mpte->mpte_alternate_port = optval;
+
                        goto out;
                default:
                        /* not eligible */
@@ -1567,6 +1590,7 @@ mptcp_getopt(struct mptses *mpte, struct sockopt *sopt)
        case TCP_ADAPTIVE_WRITE_TIMEOUT:
        case TCP_NOTSENT_LOWAT:
        case MPTCP_SERVICE_TYPE:
+       case MPTCP_ALTERNATE_PORT:
                /* eligible; get the default value just in case */
                error = mptcp_default_tcp_optval(mpte, sopt, &optval);
                break;
@@ -1586,6 +1610,9 @@ mptcp_getopt(struct mptses *mpte, struct sockopt *sopt)
        case MPTCP_SERVICE_TYPE:
                optval = mpte->mpte_svctype;
                goto out;
+       case MPTCP_ALTERNATE_PORT:
+               optval = mpte->mpte_alternate_port;
+               goto out;
        }
 
        /*
@@ -1634,6 +1661,7 @@ mptcp_default_tcp_optval(struct mptses *mpte, struct sockopt *sopt, int *optval)
        case TCP_ADAPTIVE_READ_TIMEOUT:
        case TCP_ADAPTIVE_WRITE_TIMEOUT:
        case MPTCP_SERVICE_TYPE:
+       case MPTCP_ALTERNATE_PORT:
                *optval = 0;
                break;
 
@@ -1806,6 +1834,8 @@ mptcp_sopt2str(int level, int optname)
                        return ("ADAPTIVE_WRITE_TIMEOUT");
                case MPTCP_SERVICE_TYPE:
                        return ("MPTCP_SERVICE_TYPE");
+               case MPTCP_ALTERNATE_PORT:
+                       return ("MPTCP_ALTERNATE_PORT");
                }
 
                break;
index 1ff155f549e102c8706c14846baaef3d89dd6030..d09642033b2094551a4b28bc45dc8b13347cc982 100644 (file)
@@ -41,6 +41,7 @@
 #include <mach/boolean.h>
 #include <netinet/mp_pcb.h>
 #include <netinet/tcp_var.h>
+#include <os/log.h>
 
 struct mpt_itf_info {
        uint32_t ifindex;
@@ -79,6 +80,10 @@ struct mptses {
                struct sockaddr_in6 __mpte_dst_v6;
        };
 
+       struct sockaddr_in mpte_dst_v4_nat64;
+
+       uint16_t        mpte_alternate_port;    /* Alternate port for subflow establishment (network-byte-order) */
+
        struct mptsub   *mpte_active_sub;       /* ptr to last active subf */
        uint8_t mpte_flags;                     /* per mptcp session flags */
 #define        MPTE_SND_REM_ADDR       0x01            /* Send Remove_addr option */
@@ -481,6 +486,7 @@ SYSCTL_DECL(_net_inet_mptcp);
 
 extern struct mppcbinfo mtcbinfo;
 extern struct pr_usrreqs mptcp_usrreqs;
+extern os_log_t mptcp_log_handle;
 
 /* Encryption algorithm related definitions */
 #define        SHA1_TRUNCATED          8
@@ -586,6 +592,7 @@ extern void mptcp_subflow_workloop(struct mptses *);
 
 extern void mptcp_sched_create_subflows(struct mptses *);
 
+extern void mptcp_finish_usrclosed(struct mptses *mpte);
 extern struct mptopt *mptcp_sopt_alloc(int);
 extern const char *mptcp_sopt2str(int, int);
 extern void mptcp_sopt_free(struct mptopt *);
@@ -609,6 +616,7 @@ extern int mptcp_subflow_sogetopt(struct mptses *, struct socket *,
     struct mptopt *);
 
 extern void mptcp_input(struct mptses *, struct mbuf *);
+extern boolean_t mptcp_can_send_more(struct mptcb *mp_tp, boolean_t ignore_reinject);
 extern int mptcp_output(struct mptses *);
 extern void mptcp_close_fsm(struct mptcb *, uint32_t);
 
@@ -645,6 +653,7 @@ extern int mptcp_notsent_lowat_check(struct socket *so);
 extern void mptcp_ask_symptoms(struct mptses *mpte);
 extern void mptcp_control_register(void);
 extern int mptcp_is_wifi_unusable(void);
+extern void mptcp_ask_for_nat64(struct ifnet *ifp);
 extern void mptcp_session_necp_cb(void *, int, struct necp_client_flow *);
 extern void mptcp_set_restrictions(struct socket *mp_so);
 extern int mptcp_freeq(struct mptcb *);
index cb4e31a2225c9fd5f37231a65ea99b804f520010..30c5e8e338dfd21f96cd76847c4265fd0fa5b212 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -355,13 +355,18 @@ rip_output(
        struct ip *ip;
        struct inpcb *inp = sotoinpcb(so);
        int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;
-       struct ip_out_args ipoa =
-           { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0, 0, 0 };
+       struct ip_out_args ipoa;
        struct ip_moptions *imo;
        int error = 0;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+
        int sotc = SO_TC_UNSPEC;
        int netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
+
        if (control != NULL) {
                sotc = so_tc_from_control(control, &netsvctype);
 
index d960c1f7719af34835c4a268084f0c2004d2a310..a512944680c4786b8433c8bab25008d81f14cbc7 100644 (file)
@@ -297,6 +297,8 @@ struct tcp_notify_ack_complete {
 
 #define        TCP_RXT_MINIMUM_TIMEOUT_LIMIT   (5 * 60) /* Limit is 5 minutes */
 
+#define MPTCP_ALTERNATE_PORT           0x216
+
 /*
  * The TCP_INFO socket option is a private API and is subject to change
  */
index 293a0fc0cda76681495047474c61dd2047111f2f..d746db8c535982781fa3832853e625bf6acd20f2 100644 (file)
@@ -401,8 +401,9 @@ static void tcp_cache_set_cookie_common(struct tcp_cache_key_src *tcks, u_char *
        if (tpcache == NULL)
                return;
 
-       tpcache->tc_tfo_cookie_len = len;
-       memcpy(tpcache->tc_tfo_cookie, cookie, len);
+       tpcache->tc_tfo_cookie_len = len > TFO_COOKIE_LEN_MAX ?
+               TFO_COOKIE_LEN_MAX : len;
+       memcpy(tpcache->tc_tfo_cookie, cookie, tpcache->tc_tfo_cookie_len);
 
        tcp_cache_unlock(head);
 }
index 139984932fbaaefa771de6cb9578256063356185..216814cff767947b72862b23112da076f77618bf 100644 (file)
@@ -4120,7 +4120,6 @@ trimthenstep6:
                                                    ~TMPF_PREESTABLISHED;
                                                tp->t_mpflags |=
                                                    TMPF_MPTCP_TRUE;
-                                               so->so_flags |= SOF_MPTCP_TRUE;
                                                mptcplog((LOG_DEBUG, "MPTCP "
                                                    "Sockets: %s \n",__func__),
                                                    MPTCP_SOCKET_DBG,
@@ -4942,7 +4941,8 @@ dodata:
                }
        } else {
                if ((so->so_flags & SOF_MP_SUBFLOW) && tlen == 0 &&
-                   (m->m_pkthdr.pkt_flags & PKTF_MPTCP_DFIN)) {
+                   (m->m_pkthdr.pkt_flags & PKTF_MPTCP_DFIN) &&
+                   (m->m_pkthdr.pkt_flags & PKTF_MPTCP)) {
                        m_adj(m, drop_hdrlen);  /* delayed header drop */
                        mptcp_input(tptomptp(tp)->mpt_mpte, m);
                        tp->t_flags |= TF_ACKNOW;
@@ -5865,6 +5865,8 @@ tcp_mss(struct tcpcb *tp, int offer, unsigned int input_ifscope)
        }
        tp->t_maxseg = mss;
 
+       ASSERT(tp->t_maxseg);
+
        /*
         * Update MSS using recommendation from link status report. This is
         * temporary
@@ -6338,9 +6340,9 @@ tcp_getstat SYSCTL_HANDLER_ARGS
                        proc_rele(caller_parent);
                }
 
-               if ((escape_str(command_name, strlen(command_name),
+               if ((escape_str(command_name, strlen(command_name) + 1,
                    sizeof(command_name)) == 0) &&
-                   (escape_str(parent_name, strlen(parent_name),
+                   (escape_str(parent_name, strlen(parent_name) + 1,
                    sizeof(parent_name)) == 0)) {
                        kern_asl_msg(LOG_DEBUG, "messagetracer",
                            5,
index 88ced34e95502914be7bce142bd80a5541377c1b..52884d35708f59ed900d89611ad0db170b9b25a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -1259,7 +1259,7 @@ after_sack_rexmit:
         * space. So we have to be able to go backwards and announce a smaller
         * window.
         */
-       if (!(so->so_flags & SOF_MPTCP_TRUE) &&
+       if (!(so->so_flags & SOF_MP_SUBFLOW) &&
            recwin < (int32_t)(tp->rcv_adv - tp->rcv_nxt))
                recwin = (int32_t)(tp->rcv_adv - tp->rcv_nxt);
 
@@ -2607,9 +2607,14 @@ out:
                TCP_PKTLIST_CLEAR(tp);
 
                if (error == ENOBUFS) {
+                       /*
+                        * Set retransmit timer if not currently set
+                        * when we failed to send a segment that can be
+                        * retransmitted (i.e. not pure ack or rst)
+                        */
                        if (!tp->t_timer[TCPT_REXMT] &&
                            !tp->t_timer[TCPT_PERSIST] &&
-                           (SEQ_GT(tp->snd_max, tp->snd_una) ||
+                           (len != 0 || (flags & (TH_SYN | TH_FIN)) != 0 ||
                            so->so_snd.sb_cc > 0))
                                tp->t_timer[TCPT_REXMT] =
                                        OFFSET_FROM_START(tp, tp->t_rxtcur);
@@ -2677,16 +2682,25 @@ tcp_ip_output(struct socket *so, struct tcpcb *tp, struct mbuf *pkt,
        boolean_t unlocked = FALSE;
        boolean_t ifdenied = FALSE;
        struct inpcb *inp = tp->t_inpcb;
-       struct ip_out_args ipoa =
-           { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF|IPOAF_BOUND_SRCADDR, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip_out_args ipoa;
        struct route ro;
        struct ifnet *outif = NULL;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF | IPOAF_BOUND_SRCADDR;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 #if INET6
-       struct ip6_out_args ip6oa =
-           { IFSCOPE_NONE, { 0 }, IP6OAF_SELECT_SRCIF|IP6OAF_BOUND_SRCADDR, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip6_out_args ip6oa;
        struct route_in6 ro6;
+
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = IFSCOPE_NONE;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
        struct flowadv *adv =
            (isipv6 ? &ip6oa.ip6oa_flowadv : &ipoa.ipoa_flowadv);
 #else /* INET6 */
index 2d6d4d1bf4de20a9b036cf111df1b3748a54ba78..363dea99f8e46a9333ab2a3acac05999c9315914 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -484,7 +484,8 @@ tcp_init(struct protosw *pp, struct domain *dp)
 
        /* expose initial uptime/now via systcl for utcp to keep time sync */
        tcp_now_init = tcp_now;
-       tcp_microuptime_init = tcp_uptime.tv_sec * 1000 + tcp_uptime.tv_usec;
+       tcp_microuptime_init =
+           tcp_uptime.tv_usec + (tcp_uptime.tv_sec * USEC_PER_SEC);
        SYSCTL_SKMEM_UPDATE_FIELD(tcp.microuptime_init, tcp_microuptime_init);
        SYSCTL_SKMEM_UPDATE_FIELD(tcp.now_init, tcp_now_init);
 
@@ -953,9 +954,12 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
 
 #if INET6
        if (isipv6) {
-               struct ip6_out_args ip6oa = { tra->ifscope, { 0 },
-                   IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR, 0,
-                   SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC};
+               struct ip6_out_args ip6oa;
+               bzero(&ip6oa, sizeof(ip6oa));
+               ip6oa.ip6oa_boundif = tra->ifscope;
+               ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR;
+               ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+               ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
                if (tra->ifscope != IFSCOPE_NONE)
                        ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
@@ -987,9 +991,12 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
        } else
 #endif /* INET6 */
        {
-               struct ip_out_args ipoa = { tra->ifscope, { 0 },
-                   IPOAF_SELECT_SRCIF | IPOAF_BOUND_SRCADDR, 0,
-                   SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+               struct ip_out_args ipoa;
+               bzero(&ipoa, sizeof(ipoa));
+               ipoa.ipoa_boundif = tra->ifscope;
+               ipoa.ipoa_flags = IPOAF_SELECT_SRCIF | IPOAF_BOUND_SRCADDR;
+               ipoa.ipoa_sotc = SO_TC_UNSPEC;
+               ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
                if (tra->ifscope != IFSCOPE_NONE)
                        ipoa.ipoa_flags |= IPOAF_BOUND_IF;
@@ -2141,7 +2148,7 @@ tcp_get_ports_used(uint32_t ifindex, int protocol, uint32_t flags,
 {
                inpcb_get_ports_used(ifindex, protocol, flags, bitfield,
                    &tcbinfo);
-}
+       }
 
 __private_extern__ uint32_t
 tcp_count_opportunistic(unsigned int ifindex, u_int32_t flags)
@@ -2672,6 +2679,8 @@ tcp_mtudisc(
 
                tp->t_maxseg = mss;
 
+               ASSERT(tp->t_maxseg);
+
                /*
                 * Reset the slow-start flight size as it may depends on the
                 * new MSS
index 2c861120e8e0f011eb442a405b1f7b9cbbd02abf..417b61b89b9a438e6c4f8c92796272d30442cbee 100644 (file)
@@ -842,6 +842,7 @@ tcp_pmtud_revert_segment_size(struct tcpcb *tp)
        optlen = tp->t_maxopd - tp->t_maxseg;
        tp->t_maxopd = tp->t_pmtud_saved_maxopd;
        tp->t_maxseg = tp->t_maxopd - optlen;
+
        /*
         * Reset the slow-start flight size as it
         * may depend on the new MSS
index 3c368cb52f3411c64d213ae84840c10346d7a7d1..1af338ade1997928b275e7d7fab1c09155ca0890 100644 (file)
@@ -412,15 +412,6 @@ tcp_connect_complete(struct socket *so)
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
 
-#if NECP
-       /* Update NECP client with connected five-tuple */
-       if (!uuid_is_null(inp->necp_client_uuid)) {
-               socket_unlock(so, 0);
-               necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
-               socket_lock(so, 0);
-       }
-#endif /* NECP */
-
        /* TFO delays the tcp_output until later, when the app calls write() */
        if (so->so_flags1 & SOF1_PRECONNECT_DATA) {
                if (!necp_socket_is_allowed_to_send_recv(sotoinpcb(so), NULL, NULL))
@@ -433,6 +424,15 @@ tcp_connect_complete(struct socket *so)
                error = tcp_output(tp);
        }
 
+#if NECP
+       /* Update NECP client with connected five-tuple */
+       if (error == 0 && !uuid_is_null(inp->necp_client_uuid)) {
+               socket_unlock(so, 0);
+               necp_client_assign_from_socket(so->last_pid, inp->necp_client_uuid, inp);
+               socket_lock(so, 0);
+       }
+#endif /* NECP */
+
        return (error);
 }
 
@@ -601,6 +601,9 @@ tcp_usr_connectx_common(struct socket *so, int af,
                *pcid = 1; /* there is only one connection in regular TCP */
 
 done:
+       if (error && error != EINPROGRESS)
+               so->so_flags1 &= ~SOF1_PRECONNECT_DATA;
+
        inp->inp_flags2 &= ~INP2_CONNECT_IN_PROGRESS;
        return (error);
 }
@@ -1784,9 +1787,9 @@ tcp_sysctl_info(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused
                        proc_rele(caller_parent);
                }
 
-               if ((escape_str(command_name, strlen(command_name),
+               if ((escape_str(command_name, strlen(command_name) + 1,
                    sizeof(command_name)) == 0) &&
-                   (escape_str(parent_name, strlen(parent_name),
+                   (escape_str(parent_name, strlen(parent_name) + 1,
                    sizeof(parent_name)) == 0)) {
                        kern_asl_msg(LOG_DEBUG, "messagetracer",
                            5,
@@ -1838,30 +1841,30 @@ tcp_lookup_peer_pid_locked(struct socket *so, pid_t *out_pid)
        uint16_t                lport = inp->inp_lport;
        uint16_t                fport = inp->inp_fport;
        struct inpcb    *finp = NULL;
+       struct  in6_addr laddr6, faddr6;
+       struct in_addr laddr4, faddr4;
 
        if (inp->inp_vflag & INP_IPV6) {
-               struct  in6_addr        laddr6 = inp->in6p_laddr;
-               struct  in6_addr        faddr6 = inp->in6p_faddr;
-               socket_unlock(so, 0);
+               laddr6 = inp->in6p_laddr;
+               faddr6 = inp->in6p_faddr;
+       } else if (inp->inp_vflag & INP_IPV4) {
+               laddr4 = inp->inp_laddr;
+               faddr4 = inp->inp_faddr;
+       }
+
+       socket_unlock(so, 0);
+       if (inp->inp_vflag & INP_IPV6) {
                finp = in6_pcblookup_hash(&tcbinfo, &laddr6, lport, &faddr6, fport, 0, NULL);
-               socket_lock(so, 0);
        } else if (inp->inp_vflag & INP_IPV4) {
-               struct  in_addr laddr4 = inp->inp_laddr;
-               struct  in_addr faddr4 = inp->inp_faddr;
-               socket_unlock(so, 0);
                finp = in_pcblookup_hash(&tcbinfo, laddr4, lport, faddr4, fport, 0, NULL);
-               socket_lock(so, 0);
        }
 
        if (finp) {
                *out_pid = finp->inp_socket->last_pid;
                error = 0;
-               /* Avoid deadlock due to same inpcb for loopback socket */
-               if (inp == finp)
-                       in_pcb_checkstate(finp, WNT_RELEASE, 1);
-               else
-                       in_pcb_checkstate(finp, WNT_RELEASE, 0);
+               in_pcb_checkstate(finp, WNT_RELEASE, 0);
        }
+       socket_lock(so, 0);
 
        return error;
 }
@@ -2758,10 +2761,10 @@ tcp_usrclosed(struct tcpcb *tp)
 
        case TCPS_CLOSED:
        case TCPS_LISTEN:
+       case TCPS_SYN_SENT:
                tp = tcp_close(tp);
                break;
 
-       case TCPS_SYN_SENT:
        case TCPS_SYN_RECEIVED:
                tp->t_flags |= TF_NEEDFIN;
                break;
index 0c4945e79b07f3e149b2767993493c677a7d39a9..a04bfcca4591e3bc407b853c0a0a7a8d05473154 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -1311,7 +1311,7 @@ udp_get_ports_used(uint32_t ifindex, int protocol, uint32_t flags,
 {
                inpcb_get_ports_used(ifindex, protocol, flags, bitfield,
                    &udbinfo);
-}
+       }
 
 __private_extern__ uint32_t
 udp_count_opportunistic(unsigned int ifindex, u_int32_t flags)
@@ -1414,8 +1414,12 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
        struct mbuf *inpopts;
        struct ip_moptions *mopts;
        struct route ro;
-       struct ip_out_args ipoa =
-           { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0, 0, 0 };
+       struct ip_out_args ipoa;
+
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+
        struct ifnet *outif = NULL;
        struct flowadv *adv = &ipoa.ipoa_flowadv;
        int sotc = SO_TC_UNSPEC;
index f80a4154aa04abf5d0cda74d66ac9aa9335a7a0c..853d97702f1ec23b3c7d26fac5702cd47488ca9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -2138,10 +2138,14 @@ icmp6_reflect(struct mbuf *m, size_t off)
        struct sockaddr_in6 sa6_src, sa6_dst;
        struct nd_ifinfo *ndi = NULL;
        u_int32_t oflow;
-       struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 },
-           IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR |
-           IP6OAF_INTCOPROC_ALLOWED | IP6OAF_AWDL_UNRESTRICTED, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip6_out_args ip6oa;
+
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = IFSCOPE_NONE;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR |
+           IP6OAF_INTCOPROC_ALLOWED | IP6OAF_AWDL_UNRESTRICTED;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        if (!(m->m_pkthdr.pkt_flags & PKTF_LOOP) && m->m_pkthdr.rcvif != NULL) {
                ip6oa.ip6oa_boundif = m->m_pkthdr.rcvif->if_index;
@@ -2569,9 +2573,13 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
        u_char *p;
        struct ifnet *outif = NULL;
        struct sockaddr_in6 src_sa;
-       struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 },
-           IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip6_out_args ip6oa;
+
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = IFSCOPE_NONE;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
 
        icmp6_errcount(&icmp6stat.icp6s_outerrhist, ND_REDIRECT, 0);
 
index 29cbedd508336d8055245d47959790aba1107faf..3118b7bae193af127f2095e16c51ab55ce17296d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -198,13 +198,17 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct proc *p)
 
        if (!in6_ifaddrs) /* XXX broken! */
                return (EADDRNOTAVAIL);
-       if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
-               return (EINVAL);
        if (!(so->so_options & (SO_REUSEADDR|SO_REUSEPORT)))
                wild = 1;
 
        socket_unlock(so, 0); /* keep reference */
        lck_rw_lock_exclusive(pcbinfo->ipi_lock);
+       if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
+               /* another thread completed the bind */
+               lck_rw_done(pcbinfo->ipi_lock);
+               socket_lock(so, 0);
+               return (EINVAL);
+       }
 
        bzero(&sin6, sizeof (sin6));
        if (nam != NULL) {
index a987f42508374fb73783010e98a787e6c7b9818b..42fe27ad4e690ebaf8436399e42fe82f25f997af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -554,13 +554,18 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
        struct ifnet *ifp = NULL;
        struct in6_pktinfo *pi = NULL;
        struct ip6_moptions *mopts;
-       struct ip6_out_args ip6oa = { ifscope, { 0 }, IP6OAF_SELECT_SRCIF, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip6_out_args ip6oa;
        boolean_t inp_debug = FALSE;
        uint32_t hint_mask = 0;
        int prefer_tempaddr = 0;
        struct ifnet *sifp = NULL;
 
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = ifscope;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
        *errorp = 0;
        if (ifpp != NULL)
                *ifpp = NULL;
@@ -1365,13 +1370,15 @@ int
 in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p,
     int locked)
 {
-#pragma unused(laddr)
        struct socket *so = inp->inp_socket;
        u_int16_t lport = 0, first, last, *lastport;
        int count, error = 0, wild = 0;
+       boolean_t counting_down;
        bool found;
        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
        kauth_cred_t cred;
+
+       (void)laddr;
        if (!locked) { /* Make sure we don't run into a deadlock: 4052373 */
                if (!lck_rw_try_lock_exclusive(pcbinfo->ipi_lock)) {
                        socket_unlock(inp->inp_socket, 0);
@@ -1423,63 +1430,43 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p,
        /*
         * Simple check to ensure all ports are not used up causing
         * a deadlock here.
-        *
-        * We split the two cases (up and down) so that the direction
-        * is not being tested on each round of the loop.
         */
+       found = false;
        if (first > last) {
-               /*
-                * counting down
-                */
+               /* counting down */
                count = first - last;
-               found = false;
-
-               do {
-                       if (count-- < 0) {      /* completely used? */
-                               /*
-                                * Undo any address bind that may have
-                                * occurred above.
-                                */
-                               inp->in6p_laddr = in6addr_any;
-                               inp->in6p_last_outifp = NULL;
-                               if (!locked)
-                                       lck_rw_done(pcbinfo->ipi_lock);
-                               return (EAGAIN);
-                       }
-                       --*lastport;
-                       if (*lastport > first || *lastport < last)
-                               *lastport = first;
-                       lport = htons(*lastport);
-
-                       found = in6_pcblookup_local(pcbinfo, &inp->in6p_laddr,
-                           lport, wild) == NULL;
-               } while (!found);
+               counting_down = TRUE;
        } else {
                /* counting up */
                count = last - first;
-               found = false;
-
-               do {
-                       if (count-- < 0) {      /* completely used? */
-                               /*
-                                * Undo any address bind that may have
-                                * occurred above.
-                                */
-                               inp->in6p_laddr = in6addr_any;
-                               inp->in6p_last_outifp = NULL;
-                               if (!locked)
-                                       lck_rw_done(pcbinfo->ipi_lock);
-                               return (EAGAIN);
+               counting_down = FALSE;
+       }
+       do {
+               if (count-- < 0) {      /* completely used? */
+                       /*
+                        * Undo any address bind that may have
+                        * occurred above.
+                        */
+                       inp->in6p_laddr = in6addr_any;
+                       inp->in6p_last_outifp = NULL;
+                       if (!locked)
+                               lck_rw_done(pcbinfo->ipi_lock);
+                       return (EAGAIN);
+               }
+               if (counting_down) {
+                       --*lastport;
+                       if (*lastport > first || *lastport < last) {
+                               *lastport = first;
                        }
+               } else {
                        ++*lastport;
                        if (*lastport < first || *lastport > last)
                                *lastport = first;
-                       lport = htons(*lastport);
-
-                       found = in6_pcblookup_local(pcbinfo, &inp->in6p_laddr,
-                           lport, wild) == NULL;
-               } while (!found);
-       }
+               }
+               lport = htons(*lastport);
+               found = (in6_pcblookup_local(pcbinfo, &inp->in6p_laddr,
+                                            lport, wild) == NULL);
+       } while (!found);
 
        inp->inp_lport = lport;
        inp->inp_flags |= INP_ANONPORT;
index b3c2bcfcda1a82875dd993d0718a1f80681d340c..6ca8bba66dfb6022a7ab740e870af74efcb1462f 100644 (file)
@@ -1030,6 +1030,12 @@ hbhcheck:
        if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
                struct ip6_hbh *hbh;
 
+               /*
+                * Mark the packet to imply that HBH option has been checked.
+                * This can only be true is the packet came in unfragmented
+                * or if the option is in the first fragment
+                */
+               m->m_pkthdr.pkt_flags |= PKTF_HBH_CHKED;
                if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
 #if 0  /* touches NULL pointer */
                        in6_ifstat_inc(inifp, ifs6_in_discard);
@@ -1177,6 +1183,20 @@ injectit:
                struct ipfilter *filter;
                int (*pr_input)(struct mbuf **, int *, int);
 
+               /*
+                * This would imply either IPPROTO_HOPOPTS was not the first
+                * option or it did not come in the first fragment.
+                */
+               if (nxt == IPPROTO_HOPOPTS &&
+                   (m->m_pkthdr.pkt_flags & PKTF_HBH_CHKED) == 0) {
+                       /*
+                        * This implies that HBH option was not contained
+                        * in the first fragment
+                        */
+                       ip6stat.ip6s_badoptions++;
+                       goto bad;
+               }
+
                if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
                        ip6stat.ip6s_toomanyhdr++;
                        goto bad;
@@ -1192,7 +1212,6 @@ injectit:
                        goto bad;
                }
 
-
 #if IPSEC
                /*
                 * enforce IPsec policy checking if we are seeing last header.
index 1ba0680113a8fc26581b4169ec09637d142b0b8d..283158d5843843c2efb2517025f710c7ac5b2df9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -3689,8 +3689,13 @@ ipsec6_output_tunnel_internal(struct ipsec_output_state *state, struct secasvar
                        struct sockaddr_in* dst4;
                        struct route *ro4 = NULL;
                        struct route  ro4_copy;
-                       struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0,
-                           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+                       struct ip_out_args ipoa;
+
+                       bzero(&ipoa, sizeof(ipoa));
+                       ipoa.ipoa_boundif = IFSCOPE_NONE;
+                       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+                       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+                       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
                        
                        if (must_be_last)
                                *must_be_last = 1;
@@ -4680,12 +4685,16 @@ ipsec_send_natt_keepalive(
        struct mbuf            *m;
        struct ip          *ip;
        int                 error;
-       struct ip_out_args  ipoa =
-           { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip_out_args  ipoa;
        struct route        ro;
        int keepalive_interval = natt_keepalive_interval;
 
+       bzero(&ipoa, sizeof(ipoa));
+       ipoa.ipoa_boundif = IFSCOPE_NONE;
+       ipoa.ipoa_flags = IPOAF_SELECT_SRCIF;
+       ipoa.ipoa_sotc = SO_TC_UNSPEC;
+       ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
        LCK_MTX_ASSERT(sadb_mutex, LCK_MTX_ASSERT_NOTOWNED);
 
        if ((esp_udp_encap_port & 0xFFFF) == 0 || sav->remote_ike_port == 0) return FALSE;
index 495a3b3044c8bb8824bcab9a0e6e92cc607511ac..0b150814ae62e491db59bc67552901d4aa6a5b7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -811,7 +811,8 @@ again:
         * resolved, however right now we do not install more than one default
         * route per interface in the routing table.
         */
-       if (send_nc_failure_kev && ifp->if_addrlen == IF_LLREACH_MAXLEN) {
+       if (send_nc_failure_kev && ifp != NULL &&
+           ifp->if_addrlen == IF_LLREACH_MAXLEN) {
                struct kev_msg ev_msg;
                struct kev_nd6_ndfailure nd6_ndfailure;
                bzero(&ev_msg, sizeof(ev_msg));
@@ -1234,6 +1235,7 @@ again:
 addrloop:
        lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
        for (ia6 = in6_ifaddrs; ia6; ia6 = nia6) {
+               int oldflags = ia6->ia6_flags;
                ap->found++;
                nia6 = ia6->ia_next;
                IFA_LOCK(&ia6->ia_ifa);
@@ -1305,21 +1307,21 @@ addrloop:
                        ap->aging_lazy++;
                IFA_LOCK_ASSERT_HELD(&ia6->ia_ifa);
                if (IFA6_IS_DEPRECATED(ia6, timenow)) {
-                       int oldflags = ia6->ia6_flags;
                        ia6->ia6_flags |= IN6_IFF_DEPRECATED;
 
-                       /*
-                        * Only enqueue the Deprecated event when the address just
-                        * becomes deprecated.
-                        * Keep it limited to the stable address it is common for
-                        * older temporary addresses to get deprecated while we generate
-                        * new ones.
-                        */
-                       if((oldflags & IN6_IFF_DEPRECATED) == 0 &&
-                           (ia6->ia6_flags & IN6_IFF_TEMPORARY) == 0) {
-                               in6_event_enqueue_nwk_wq_entry(IN6_ADDR_MARKED_DEPRECATED,
-                                   ia6->ia_ifa.ifa_ifp, &ia6->ia_addr.sin6_addr,
-                                   0);
+                       if((oldflags & IN6_IFF_DEPRECATED) == 0) {
+                               /*
+                                * Only enqueue the Deprecated event when the address just
+                                * becomes deprecated.
+                                * Keep it limited to the stable address as it is common for
+                                * older temporary addresses to get deprecated while we generate
+                                * new ones.
+                                */
+                               if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) == 0) {
+                                       in6_event_enqueue_nwk_wq_entry(IN6_ADDR_MARKED_DEPRECATED,
+                                           ia6->ia_ifa.ifa_ifp, &ia6->ia_addr.sin6_addr,
+                                           0);
+                               }
                        }
                        /*
                         * If a temporary address has just become deprecated,
index 855b65e4cc55b02598f868805d246ba44246636b..4ef91c84cfcce2802da94768f60252735afdea77 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -572,18 +572,20 @@ nd6_ns_output(
        int flags;
        caddr_t mac;
        struct route_in6 ro;
-       struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 },
-           IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR |
-           IP6OAF_AWDL_UNRESTRICTED | IP6OAF_INTCOPROC_ALLOWED, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
+       struct ip6_out_args ip6oa;
        u_int32_t rtflags = 0;
 
        if ((ifp->if_eflags & IFEF_IPV6_ND6ALT) || IN6_IS_ADDR_MULTICAST(taddr6))
                return;
 
        bzero(&ro, sizeof(ro));
-
+       bzero(&ip6oa, sizeof(ip6oa));
        ip6oa.ip6oa_boundif = ifp->if_index;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR |
+           IP6OAF_AWDL_UNRESTRICTED | IP6OAF_INTCOPROC_ALLOWED;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
        ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
 
        /* estimate the size of message */
@@ -1173,16 +1175,17 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
                         * issue a callback for LLENTRY changed.
                         */
                        /* Enqueue work item to invoke callback for this route entry */
-                       route_event_enqueue_nwk_wq_entry(rt, NULL,
-                           ROUTE_LLENTRY_CHANGED, NULL, TRUE);
+                       if (llchange) {
+                               route_event_enqueue_nwk_wq_entry(rt, NULL,
+                                   ROUTE_LLENTRY_CHANGED, NULL, TRUE);
+                       }
 
                        /*
-                        * If the entry is no longer a router, the logic post this processing
-                        * gets rid of all the route entries having the current entry as a next
-                        * hop.
-                        * So only walk the tree here when there's no such change.
+                        * If the router's link-layer address has changed,
+                        * notify routes using this as gateway so they can
+                        * update any cached information.
                         */
-                       if (ln->ln_router && is_router) {
+                       if (ln->ln_router && is_router && llchange) {
                                struct radix_node_head  *rnh = NULL;
                                struct route_event rt_ev;
                                route_event_init(&rt_ev, rt, NULL, ROUTE_LLENTRY_CHANGED);
@@ -1342,16 +1345,19 @@ nd6_na_output(
        struct sockaddr_in6 dst_sa;
        int icmp6len, maxlen, error;
         struct ifnet *outif = NULL;
-       struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 },
-           IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR |
-           IP6OAF_AWDL_UNRESTRICTED | IP6OAF_INTCOPROC_ALLOWED, 0,
-           SO_TC_UNSPEC, _NET_SERVICE_TYPE_UNSPEC };
 
+       struct ip6_out_args ip6oa;
        bzero(&ro, sizeof(ro));
 
        daddr6 = *daddr6_0;     /* make a local copy for modification */
 
+       bzero(&ip6oa, sizeof(ip6oa));
        ip6oa.ip6oa_boundif = ifp->if_index;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR |
+           IP6OAF_AWDL_UNRESTRICTED | IP6OAF_INTCOPROC_ALLOWED;
+       ip6oa.ip6oa_sotc = SO_TC_UNSPEC;
+       ip6oa.ip6oa_netsvctype = _NET_SERVICE_TYPE_UNSPEC;
+
        ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF;
 
        /* estimate the size of message */
index 8502334ea4754d839c8c8ca1708aa5358e64cad0..f54c20f547f9609aeea6598d654fdb1b2b38a17a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -3072,10 +3072,12 @@ pfxlist_onlink_check(void)
                        } else {
                                NDPR_UNLOCK(ndpr);
                                IFA_LOCK(&ifa->ia_ifa);
-                               ifa->ia6_flags |= IN6_IFF_DETACHED;
-                               in6_event_enqueue_nwk_wq_entry(IN6_ADDR_MARKED_DETACHED,
-                                   ifa->ia_ifa.ifa_ifp, &ifa->ia_addr.sin6_addr,
-                                   0);
+                               if ((ifa->ia6_flags & IN6_IFF_DETACHED) == 0) {
+                                       ifa->ia6_flags |= IN6_IFF_DETACHED;
+                                       in6_event_enqueue_nwk_wq_entry(IN6_ADDR_MARKED_DETACHED,
+                                           ifa->ia_ifa.ifa_ifp, &ifa->ia_addr.sin6_addr,
+                                           0);
+                               }
                                IFA_UNLOCK(&ifa->ia_ifa);
                        }
                        NDPR_REMREF(ndpr);
index d7c6f689fb2dcad1301e6c6144c98984c742ab25..ec7f823fb1809d78d737304ee349e35515d59d3a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -349,12 +349,15 @@ rip6_output(
        int type = 0, code = 0;         /* for ICMPv6 output statistics only */
        int sotc = SO_TC_UNSPEC;
        int netsvctype = _NET_SERVICE_TYPE_UNSPEC;
-       struct ip6_out_args ip6oa =
-           { IFSCOPE_NONE, { 0 }, IP6OAF_SELECT_SRCIF, 0, 0, 0 };
+       struct ip6_out_args ip6oa;
        int flags = IPV6_OUTARGS;
 
        in6p = sotoin6pcb(so);
 
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = IFSCOPE_NONE;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF;
+
        if (in6p == NULL
 #if NECP
                || (necp_socket_should_use_flow_divert(in6p))
index 3db74ee521b44575d98c615bf6c3e96d181bf678..fdda7e512c838c4eb81bd612c41b0d3528e66d87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -161,13 +161,16 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct sockaddr *addr6,
        struct  in6_addr storage;
        int sotc = SO_TC_UNSPEC;
        int netsvctype = _NET_SERVICE_TYPE_UNSPEC;
-       struct ip6_out_args ip6oa =
-           { IFSCOPE_NONE, { 0 }, IP6OAF_SELECT_SRCIF, 0, 0, 0 };
+       struct ip6_out_args ip6oa;
        struct flowadv *adv = &ip6oa.ip6oa_flowadv;
        struct socket *so = in6p->in6p_socket;
        struct route_in6 ro;
        int flowadv = 0;
 
+       bzero(&ip6oa, sizeof(ip6oa));
+       ip6oa.ip6oa_boundif = IFSCOPE_NONE;
+       ip6oa.ip6oa_flags = IP6OAF_SELECT_SRCIF;
+
        /* Enable flow advisory only when connected */
        flowadv = (so->so_state & SS_ISCONNECTED) ? 1 : 0;
 
index a7935a5f20202faf1c7b2e0a7093191fa08af72d..5272fa8df12f28854c1671221d9ebc148d9ddc4f 100644 (file)
@@ -1171,12 +1171,17 @@ key_do_allocsa_policy(
                if (candidate->lft_c->sadb_lifetime_addtime <
                        sav->lft_c->sadb_lifetime_addtime) {
                        d = candidate;
-                       if ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0)
+                       if ((sah->saidx.mode == IPSEC_MODE_TUNNEL &&
+                                ((sav->flags & SADB_X_EXT_NATT) != 0)) ||
+                               (sah->saidx.mode == IPSEC_MODE_TRANSPORT &&
+                                ((sav->flags & SADB_X_EXT_NATT_MULTIPLEUSERS) != 0))) {
                                natt_candidate = sav;
-                       else
+                       } else {
                                no_natt_candidate = sav;
-               } else
+                       }
+               } else {
                        d = sav;
+               }
                
                /*
                 * prepared to delete the SA when there is more
index 20fa08bd8ff4e8138979c96489b8c73961705065..7ae7758e00307a0d5eebba6e28ccb5f12351aa82 100644 (file)
@@ -126,6 +126,7 @@ struct rpc_reply {
 };
 
 #define MIN_REPLY_HDR 16       /* xid, dir, astat, errno */
+#define REPLY_SIZE 24          /* xid, dir, astat, rpu_ok */
 
 /*
  * What is the longest we will wait before re-sending a request?
@@ -492,8 +493,16 @@ krpc_call(
                                goto out;
                        }
 
+
+                       if (mbuf_len(m) < REPLY_SIZE) {
+                               error = RPC_SYSTEM_ERR;
+                       }
+                       else {
+                               error = ntohl(reply->rp_u.rpu_ok.rp_rstatus);
+                       }
+
                        /* Did the call succeed? */
-                       if ((error = ntohl(reply->rp_u.rpu_ok.rp_rstatus)) != 0) {
+                       if (error != 0) {
                                printf("rpc status=%d\n", error);
                                /* convert rpc error to errno */
                                switch (error) {
index c0c5877f622a1cfeaa83be1a9a2a5738007711b9..56d3be6642f423401bea722ecee1640a1287336e 100644 (file)
@@ -460,6 +460,7 @@ bp_whoami(struct sockaddr_in *bpsin,
        size_t msg_len, cn_len, dn_len;
        u_char *p;
        int32_t *lp;
+        size_t encapsulated_size;
 
        /*
         * Get message buffer of sufficient size.
@@ -508,8 +509,10 @@ bp_whoami(struct sockaddr_in *bpsin,
        bpsin->sin_addr.s_addr = sin.sin_addr.s_addr;
 
        /* length of encapsulated results */
-       if (msg_len < (ntohl(*lp) + sizeof(*lp)))
+       if (os_add_overflow((size_t) ntohl(*lp), sizeof(*lp), &encapsulated_size)
+               || msg_len < encapsulated_size) {
                goto bad;
+       }
        msg_len = ntohl(*lp++);
        p = (u_char*)lp;
 
@@ -518,7 +521,7 @@ bp_whoami(struct sockaddr_in *bpsin,
                goto bad;
        str = (struct rpc_string *)p;
        cn_len = ntohl(str->len);
-       if (msg_len < cn_len)
+       if ((msg_len - 4) < cn_len)
                goto bad;
        if (cn_len >= MAXHOSTNAMELEN)
                goto bad;
@@ -533,7 +536,7 @@ bp_whoami(struct sockaddr_in *bpsin,
                goto bad;
        str = (struct rpc_string *)p;
        dn_len = ntohl(str->len);
-       if (msg_len < dn_len)
+       if ((msg_len - 4) < dn_len)
                goto bad;
        if (dn_len >= MAXHOSTNAMELEN)
                goto bad;
@@ -585,8 +588,8 @@ bp_getfile(struct sockaddr_in *bpsin,
        struct bp_inaddr *bia;
        struct sockaddr_in *sin;
        u_char *p, *q;
-       int error, msg_len;
-       int cn_len, key_len, sn_len, path_len;
+       int error;
+       size_t msg_len, cn_len, key_len, sn_len, path_len;
 
        /*
         * Get message buffer of sufficient size.
@@ -628,11 +631,11 @@ bp_getfile(struct sockaddr_in *bpsin,
        msg_len = mbuf_len(m);
 
        /* server name */
-       if (msg_len < (int)sizeof(*str))
+       if (msg_len < sizeof(*str))
                goto bad;
        str = (struct rpc_string *)p;
        sn_len = ntohl(str->len);
-       if (msg_len < sn_len)
+       if ((msg_len - 4) < sn_len)
                goto bad;
        if (sn_len >= MAXHOSTNAMELEN)
                goto bad;
@@ -642,7 +645,7 @@ bp_getfile(struct sockaddr_in *bpsin,
        msg_len -= RPC_STR_SIZE(sn_len);
 
        /* server IP address (mountd) */
-       if (msg_len < (int)sizeof(*bia))
+       if (msg_len < sizeof(*bia))
                goto bad;
        bia = (struct bp_inaddr *)p;
        if (bia->atype != htonl(1))
@@ -660,11 +663,11 @@ bp_getfile(struct sockaddr_in *bpsin,
        msg_len -= sizeof(*bia);
 
        /* server pathname */
-       if (msg_len < (int)sizeof(*str))
+       if (msg_len < sizeof(*str))
                goto bad;
        str = (struct rpc_string *)p;
        path_len = ntohl(str->len);
-       if (msg_len < path_len)
+       if ((msg_len - 4) < path_len)
                goto bad;
        if (path_len >= MAXPATHLEN)
                goto bad;
@@ -702,7 +705,8 @@ md_mount(struct sockaddr_in *mdsin,         /* mountd server address */
                u_char  data[NFSX_V3FHMAX + sizeof(u_int32_t)];
        } *rdata;
        mbuf_t m;
-       int error, mlen, slen;
+       size_t mlen;
+       int error, slen;
        int mntversion = v3 ? RPCMNT_VER3 : RPCMNT_VER1;
        int proto = (sotype == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP;
        in_port_t mntport, nfsport;
@@ -742,7 +746,7 @@ md_mount(struct sockaddr_in *mdsin,         /* mountd server address */
         * + a v3 filehandle length + a v3 filehandle
         */
        mlen = mbuf_len(m);
-       if (mlen < (int)sizeof(u_int32_t))
+       if (mlen < sizeof(u_int32_t))
                goto bad;
        rdata = mbuf_data(m);
        error = ntohl(rdata->errno);
@@ -751,16 +755,17 @@ md_mount(struct sockaddr_in *mdsin,               /* mountd server address */
        if (v3) {
                u_int32_t fhlen;
                u_char *fh;
-               if (mlen < (int)sizeof(u_int32_t)*2)
+               if (mlen < sizeof(u_int32_t)*2)
                        goto bad;
                fhlen = ntohl(*(u_int32_t*)rdata->data);
                fh = rdata->data + sizeof(u_int32_t);
-               if (mlen < (int)(sizeof(u_int32_t)*2 + fhlen))
+               if (mlen < (sizeof(u_int32_t)*2 + fhlen)
+                       || fhlen >= (NFSX_V3FHMAX + sizeof(u_int32_t)))
                        goto bad;
                bcopy(fh, fhp, fhlen);
                *fhlenp = fhlen;
        } else {
-               if (mlen < ((int)sizeof(u_int32_t) + NFSX_V2FH))
+               if (mlen < (sizeof(u_int32_t) + NFSX_V2FH))
                        goto bad;
                bcopy(rdata->data, fhp, NFSX_V2FH);
                *fhlenp = NFSX_V2FH;
index 5ade6666b1da6f024062f3b79321807646b1bd01..917927c01b6d2ddd15d8f84d1bfb49283c0093bf 100644 (file)
@@ -3247,6 +3247,7 @@ again:
        case ECONNREFUSED:
        case EHOSTDOWN:
        case EHOSTUNREACH:
+       /* case ECANCELED??? */
                needrecon = 1;
                break;
        }
@@ -3281,7 +3282,15 @@ again:
        /* only allow the following errors to be returned */
        if ((error != EINTR) && (error != ERESTART) && (error != EIO) &&
            (error != ENXIO) && (error != ETIMEDOUT))
-               error = 0;
+               /*
+                * We got some error we don't know what do do with,
+                * i.e., we're not reconnecting, we map it to
+                * EIO. Presumably our send failed and we better tell
+                * the caller so they don't wait for a reply that is
+                * never going to come.  If we are reconnecting we
+                * return 0 and the request will be resent.
+                */
+               error = needrecon ? 0 : EIO;
        return (error);
 }
 
index 89f6ca9566ccf1f31bfe10f3ffe425ec46189f36..4ba5bf1cd1fd2860353e1283a467749579dcc49c 100644 (file)
@@ -4458,6 +4458,7 @@ nfs_mount_zombie(struct nfsmount *nmp, int nm_state_flags)
        if ((nmp->nm_vers >= NFS_VER4) && nmp->nm_renew_timer) {
                thread_call_cancel(nmp->nm_renew_timer);
                thread_call_free(nmp->nm_renew_timer);
+               nmp->nm_renew_timer = NULL;
        }
 
        lck_mtx_unlock(&nmp->nm_lock);
@@ -4483,6 +4484,7 @@ nfs_mount_zombie(struct nfsmount *nmp, int nm_state_flags)
                if (nmp->nm_longid->nci_id)
                        FREE(nmp->nm_longid->nci_id, M_TEMP);
                FREE(nmp->nm_longid, M_TEMP);
+               nmp->nm_longid = NULL;
                lck_mtx_unlock(nfs_global_mutex);
        }
 
index a08ab453d95c41b25411e9907df9e4823d478520..64b4e9f05a8e0b59ceff4ada57e30aa30d62e269 100644 (file)
@@ -51,6 +51,8 @@
 #include <mach/host_special_ports.h>
 #include <mach/audit_triggers_server.h>
 
+#include <os/overflow.h>
+
 extern void ipc_port_release_send(ipc_port_t port);
 
 #if CONFIG_AUDIT
@@ -182,7 +184,10 @@ _audit_malloc(size_t size, au_malloc_type_t *type, int flags)
 #endif
 {
        struct mhdr     *hdr;
-       size_t  memsize = sizeof (*hdr) + size;
+       size_t  memsize;
+       if (os_add_overflow(sizeof(*hdr), size, &memsize)) {
+               return (NULL);
+       }
 
        if (size == 0)
                return (NULL);
index c6df6786c8ca0f6b06d2e643d7e98717018dcac4..74c747bfee85011aafc6503df102e27a472c830d 100644 (file)
@@ -100,9 +100,6 @@ struct proc_regioninfo_internal {
 #define PROC_REGION_SUBMAP     1
 #define PROC_REGION_SHARED     2
 
-void  vm_map_region_top_walk(vm_map_entry_t entry, vm_region_top_info_t top);
-void vm_map_region_walk(vm_map_t map, vm_map_offset_t a, vm_map_entry_t entry, vm_object_offset_t offset, vm_object_size_t range, vm_region_extended_info_t extended);
-kern_return_t vnode_pager_get_object_vnode(memory_object_t mem_obj, uintptr_t * vnodeaddr, uint32_t * vid);
 extern uint32_t vnode_vid(void *vp);
 #if CONFIG_IOSCHED
 kern_return_t vnode_pager_get_object_devvp(memory_object_t mem_obj, uintptr_t *devvp);
index 68b4d22d963ea4261dfffa64aaaab2a83548d2a3..4339caf7bdc81f752bf4ed4e3e39af466fbd2da4 100644 (file)
  * c99 still want long longs.  While not perfect, we allow long longs for
  * g++.
  */
-#define        __DARWIN_NO_LONG_LONG   (defined(__STRICT_ANSI__) \
-                               && (__STDC_VERSION__-0 < 199901L) \
-                               && !defined(__GNUG__))
+#if (defined(__STRICT_ANSI__) && (__STDC_VERSION__-0 < 199901L)  && !defined(__GNUG__))
+#define __DARWIN_NO_LONG_LONG 1
+#else
+#define __DARWIN_NO_LONG_LONG 0
+#endif
 
 /*****************************************
  *  Public darwin-specific feature macros
index 15a39365bf586b46d30524ed9e6d1525f74d18a9..f56878e73fe735013b007eb93a20bbafba5a5096 100644 (file)
@@ -131,8 +131,13 @@ int        csfg_get_platform_binary(struct fileglob *);
 uint8_t * csfg_get_cdhash(struct fileglob *, uint64_t, size_t *);
 int csfg_get_prod_signed(struct fileglob *);
 unsigned int csfg_get_signer_type(struct fileglob *);
+const char *csfg_get_identity(struct fileglob *fg, off_t offset);
 unsigned int csproc_get_signer_type(struct proc *);
 
+uint8_t csfg_get_platform_identifier(struct fileglob *, off_t);
+uint8_t csvnode_get_platform_identifier(struct vnode *, off_t);
+uint8_t csproc_get_platform_identifier(struct proc *);
+
 extern int cs_debug;
 
 #ifdef XNU_KERNEL_PRIVATE
index f2d613213b4400f5da4fc4dd9a81d08f64603914..cfd4c79f882e440f03b0546bae287d84d2c769d1 100644 (file)
@@ -158,6 +158,7 @@ typedef int backup_key_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in
 cpx_t cpx_alloc(size_t key_size);
 void cpx_init(cpx_t, size_t key_len);
 void cpx_free(cpx_t);
+void cpx_writeprotect(cpx_t cpx);
 __attribute__((const)) size_t cpx_size(size_t key_size);
 __attribute__((pure)) bool cpx_is_sep_wrapped_key(const struct cpx *);
 void cpx_set_is_sep_wrapped_key(struct cpx *, bool);
index d8a65de0c45f3e469a530a31542587b29e116fa6..077e1f3d9505575360de0888e925da0325136d50 100644 (file)
@@ -369,9 +369,6 @@ extern void ddi_report_dev(dev_info_t *);
 
 int ddi_getprop(dev_t dev, dev_info_t *dip, int flags, const char *name, int defvalue);
 
-extern int ddi_prop_free(void *);
-extern int ddi_prop_lookup_int_array(dev_t, dev_info_t *, uint_t, const char *, int **, uint_t *);
-
 extern int ddi_driver_major(dev_info_t *);
 
 extern int ddi_create_minor_node(dev_info_t *, const char *, int, minor_t, const char *, int);
index 794aa9acd3a98f66467d5b37c6a036501f836303..79ed9351267859686f49741d81e407623da9ba04 100644 (file)
@@ -74,26 +74,10 @@ struct eventhandler_lists_ctxt {
 };
 
 struct eventhandler_entry_arg {
-       union {
-               /* Generic cookie object reference */
-               void            *ee_voidptr;
-               /* Skywalk ids */
-               struct {
-                       pid_t           ee_fe_pid;
-                       uuid_t          ee_fe_uuid;
-                       uuid_t          ee_nx_uuid;
-               } sk_ids;
-               /* Generic UUID */
-               uuid_t          ee_uuid;
-       } ee_arg;
+       uuid_t ee_fmc_uuid;     /* Flow manager UUID */
+       uuid_t ee_fr_uuid;      /* Flow route UUID */
 };
 
-#define        ee_voidptr      ee_arg.ee_voidptr
-#define        ee_fe_pid       ee_arg.sk_ids.ee_fe_pid
-#define        ee_fe_uuid      ee_arg.sk_ids.ee_fe_uuid
-#define        ee_nx_uuid      ee_arg.sk_ids.ee_nx_uuid
-#define        ee_uuid         ee_arg.ee_uuid
-
 struct eventhandler_entry {
        TAILQ_ENTRY(eventhandler_entry) ee_link;
        int                             ee_priority;
@@ -101,8 +85,10 @@ struct eventhandler_entry {
        struct eventhandler_entry_arg   ee_arg;
 };
 
+#define        EVENTHANDLER_MAX_NAME   32
+
 struct eventhandler_list {
-       char                            *el_name;
+       char                            el_name[EVENTHANDLER_MAX_NAME];
        int                             el_flags;
 #define EHL_INITTED    (1<<0)
        u_int                           el_runcount;
@@ -115,6 +101,8 @@ typedef struct eventhandler_entry   *eventhandler_tag;
 
 #define EHL_LOCK_INIT(p)       lck_mtx_init(&(p)->el_lock, el_lock_grp, el_lock_attr)
 #define        EHL_LOCK(p)             lck_mtx_lock(&(p)->el_lock)
+#define        EHL_LOCK_SPIN(p)        lck_mtx_lock_spin(&(p)->el_lock)
+#define        EHL_LOCK_CONVERT(p)     lck_mtx_convert_spin(&(p)->el_lock)
 #define        EHL_UNLOCK(p)           lck_mtx_unlock(&(p)->el_lock)
 #define        EHL_LOCK_ASSERT(p, x)   LCK_MTX_ASSERT(&(p)->el_lock, x)
 #define        EHL_LOCK_DESTROY(p)     lck_mtx_destroy(&(p)->el_lock, el_lock_grp)
@@ -140,14 +128,16 @@ typedef struct eventhandler_entry *eventhandler_tag;
                        evhlog((LOG_DEBUG, "eventhandler_invoke: executing %p", \
                            VM_KERNEL_UNSLIDE((void *)_t->eh_func)));   \
                        _t->eh_func(_ep->ee_arg , ## __VA_ARGS__);      \
-                       EHL_LOCK((list));                               \
+                       EHL_LOCK_SPIN((list));                          \
                }                                                       \
        }                                                               \
        KASSERT((list)->el_runcount > 0,                                \
            ("eventhandler_invoke: runcount underflow"));               \
        (list)->el_runcount--;                                          \
-       if ((list)->el_runcount == 0)                                   \
+       if ((list)->el_runcount == 0) {                                 \
+               EHL_LOCK_CONVERT((list));                               \
                eventhandler_prune_list(list);                          \
+       }                                                               \
        EHL_UNLOCK((list));                                             \
 } while (0)
 
@@ -203,6 +193,7 @@ do {                                                                        \
 } while(0)
 
 void eventhandler_init(void);
+extern void eventhandler_reap_caches(boolean_t);
 eventhandler_tag eventhandler_register(struct eventhandler_lists_ctxt *evthdlr_lists_ctxt,
     struct eventhandler_list *list, const char *name, void *func, struct eventhandler_entry_arg arg, int priority);
 void eventhandler_deregister(struct eventhandler_list *list,
index 15527d926cf9659500d86742f381786d3d878023..132698775f0280611b5b9b95ce4d163bccfc873b 100644 (file)
@@ -685,6 +685,7 @@ extern void kdebug_reset(void);
 #define DBG_HFS       0x8     /* HFS-specific events; see the hfs project */
 #define DBG_APFS      0x9     /* APFS-specific events; see the apfs project */
 #define DBG_SMB       0xA     /* SMB-specific events; see the smb project */
+#define DBG_MOUNT     0xB     /* Mounting/unmounting operations */
 #define DBG_EXFAT     0xE     /* ExFAT-specific events; see the exfat project */
 #define DBG_MSDOS     0xF     /* FAT-specific events; see the msdosfs project */
 #define DBG_ACFS      0x10    /* Xsan-specific events; see the XsanFS project */
@@ -1155,11 +1156,19 @@ extern unsigned int kdebug_enable;
        do {                                                                      \
                if (KDBG_IMPROBABLE(kdebug_enable & (type))) {                        \
                        kernel_debug((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \
-                               (uintptr_t)(d), (uintptr_t)(e));                              \
+                               (uintptr_t)(d), 0);                                           \
                }                                                                     \
        } while (0)
+#define KERNEL_DEBUG_CONSTANT_IST1(x, a, b, c, d, e)                     \
+       do {                                                                       \
+               if (KDBG_IMPROBABLE(kdebug_enable)) {                         \
+                       kernel_debug1((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \
+                               (uintptr_t)(d), (uintptr_t)(e));                               \
+               }                                                                      \
+       } while (0)
 #else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
 #define KERNEL_DEBUG_CONSTANT_IST(type, x, a, b, c, d, e) do {} while (0)
+#define KERNEL_DEBUG_CONSTANT_IST1(x, a, b, c, d, e) do {} while (0)
 #endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
 
 #if NO_KDEBUG
@@ -1395,11 +1404,11 @@ void kdbg_trace_data(struct proc *proc, long *arg_pid, long *arg_uniqueid);
 void kdbg_trace_string(struct proc *proc, long *arg1, long *arg2, long *arg3, long *arg4);
 
 void kdbg_dump_trace_to_file(const char *);
-void kdebug_init(unsigned int n_events, char *filterdesc);
-void kdebug_trace_start(unsigned int n_events, const char *filterdesc, boolean_t at_wake);
+void kdebug_init(unsigned int n_events, char *filterdesc, boolean_t wrapping);
+void kdebug_trace_start(unsigned int n_events, const char *filterdesc,
+               boolean_t wrapping, boolean_t at_wake);
 void kdebug_free_early_buf(void);
 struct task;
-void kdbg_get_task_name(char*, int, struct task *task);
 boolean_t disable_wrap(uint32_t *old_slowcheck, uint32_t *old_flags);
 void enable_wrap(uint32_t old_slowcheck, boolean_t lostevents);
 void release_storage_unit(int cpu,  uint32_t storage_unit);
@@ -1468,12 +1477,12 @@ kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
 static inline void
 kdbg_set_cpu(kd_buf *kp, int cpu)
 {
-       kp->cpuid = cpu;
+       kp->cpuid = (unsigned int)cpu;
 }
 static inline int
 kdbg_get_cpu(kd_buf *kp)
 {
-       return kp->cpuid;
+       return (int)kp->cpuid;
 }
 static inline void
 kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
index 3cac39def5643196c34b69fa1254aed639a6017e..8dafca387c015f37a77fa4a0b35e7d344b4857f8 100644 (file)
@@ -505,6 +505,7 @@ struct pkthdr {
 #define        PKTF_LAST_PKT           0x10000000 /* last packet in the flow */
 #define        PKTF_MPTCP_REINJ        0x20000000 /* Packet has been reinjected for MPTCP */
 #define        PKTF_MPTCP_DFIN         0x40000000 /* Packet is a data-fin */
+#define        PKTF_HBH_CHKED          0x80000000 /* HBH option is checked */
 
 /* flags related to flow control/advisory and identification */
 #define        PKTF_FLOW_MASK  \
index 0744283f2d66ae7ff3c77aec091b1658eb807b7c..4e3d71f46409fafd941366a1038d49cdbf55bedb 100644 (file)
@@ -322,7 +322,8 @@ void personas_bootstrap(void);
 
 struct persona *persona_alloc(uid_t id, const char *login,
                              int type, int *error);
-int persona_invalidate(struct persona *persona);
+
+struct persona *persona_lookup_and_invalidate(uid_t id);
 
 static inline int proc_has_persona(proc_t p)
 {
index 58f568b4bbcc92d0200a6ec7e8bd941f0ef0547b..1933800d26c781914434d73d6c1c6298f2685dc6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2010-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
 
 #define        PRIV_NET_PRIVILEGED_MULTIPATH           10009   /* Multipath usage */
 #define        PRIV_NET_RESTRICTED_MULTIPATH_EXTENDED  10010   /* Extended multipath (more aggressive on cell) */
+#define        PRIV_NET_RESTRICTED_ROUTE_NC_READ       10011   /* Enable route neighbhor cache read operations */
+
 /*
  * IPv4 and IPv6 privileges.
  */
index f275e9f92bbfb9226aa4e019d71cfd76c17d8bd2..652cc74b96f1b64496d35f171f6ccdcbfaa54043 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -372,6 +372,7 @@ extern void proc_log_32bit_telemetry(proc_t p);
 
 #ifdef KERNEL_PRIVATE
 extern vnode_t proc_getexecutablevnode(proc_t); /* Returned with iocount, use vnode_put() to drop */
+extern int networking_memstatus_callout(proc_t p, uint32_t);
 #endif
 
 __END_DECLS
index 01c7d8b0aa214b62a9e0e391e9af2d68a602fe81..f28ae3d101ed5283a576940b7548284611e04110 100644 (file)
@@ -681,7 +681,7 @@ struct appletalk_fdinfo {
        struct appletalk_info   appletalkinfo;
 };
 
-
+typedef uint64_t proc_info_udata_t;
 
 /* defns of process file desc type */
 #define PROX_FDTYPE_ATALK      0
@@ -872,6 +872,10 @@ struct proc_fileportinfo {
 #define PROC_DIRTY_IS_DIRTY             0x4
 #define PROC_DIRTY_LAUNCH_IS_IN_PROGRESS   0x8
 
+/* Flavors for proc_udata_info */
+#define PROC_UDATA_INFO_GET            1
+#define PROC_UDATA_INFO_SET            2
+
 #ifdef PRIVATE
 
 /* Flavors for proc_pidoriginatorinfo */
@@ -905,12 +909,10 @@ struct proc_fileportinfo {
 #define PROC_FGHW_ERROR                 99 /* syscall parameter/permissions error */
 
 /* flavors for proc_piddynkqueueinfo */
-#ifdef PRIVATE
 #define PROC_PIDDYNKQUEUE_INFO         0
 #define PROC_PIDDYNKQUEUE_INFO_SIZE    (sizeof(struct kqueue_dyninfo))
 #define PROC_PIDDYNKQUEUE_EXTINFO      1
 #define PROC_PIDDYNKQUEUE_EXTINFO_SIZE (sizeof(struct kevent_extinfo))
-#endif
 
 /* __proc_info() call numbers */
 #define PROC_INFO_CALL_LISTPIDS          0x1
@@ -926,6 +928,7 @@ struct proc_fileportinfo {
 #define PROC_INFO_CALL_LISTCOALITIONS    0xb
 #define PROC_INFO_CALL_CANUSEFGHW        0xc
 #define PROC_INFO_CALL_PIDDYNKQUEUEINFO  0xd
+#define PROC_INFO_CALL_UDATA_INFO        0xe
 
 #endif /* PRIVATE */
 
index b6d40d6ee845b52108385a7b59a04ba1c3fc82a8..7119591d235adecd30e4ebd25e196a01e20b86ba 100644 (file)
@@ -409,6 +409,10 @@ struct     proc {
        _Atomic uint32_t  p_user_faults; /* count the number of user faults generated */
 
        struct os_reason     *p_exit_reason;
+
+#if !CONFIG_EMBEDDED
+       uint64_t        p_user_data;                    /* general-purpose storage for userland-provided data */
+#endif /* !CONFIG_EMBEDDED */
 };
 
 #define PGRPID_DEAD 0xdeaddead
index a7dc43f69e5bbeb24e11b401fb75ecb623cfc4ba..81792a1b9c2a78cfa4c9934ca9e7647ce459f9f3 100644 (file)
@@ -232,6 +232,7 @@ int terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_c
 #define EXEC_EXIT_REASON_FAIRPLAY_DECRYPT   10
 #define EXEC_EXIT_REASON_DECRYPT            11
 #define EXEC_EXIT_REASON_UPX                12
+#define EXEC_EXIT_REASON_NO32EXEC           13
 
 __END_DECLS
 
index 2bdccabf61c82a52084e2c284549aa2ef7b540c1..3602f776496324dab3cd03629502fa55a86f4092 100644 (file)
 #define        SO_TRAFFIC_CLASS_DBG    0x1088          /* Debug traffic class (struct so_tcdbg) */
 #define        SO_TRAFFIC_CLASS_STATS  0x1089          /* Traffic class statistics */
 #define        SO_PRIVILEGED_TRAFFIC_CLASS 0x1090      /* Privileged traffic class (bool) */
+#define        SO_DEFUNCTIT    0x1091          /* Defunct a socket (only in internal builds) */
 #define        SO_DEFUNCTOK    0x1100          /* can be defunct'd */
 #define        SO_ISDEFUNCT    0x1101          /* get defunct status */
 
index 17e1e2c35a0aaf3b12475cf50d19dd7e586271d5..b0be72420adc88f0e9f4b27f40a4d16a57959675 100644 (file)
@@ -275,7 +275,6 @@ struct socket {
 #define        SOF_ENABLE_MSGS         0x00400000 /* TCP must enable message delivery */
 #define        SOF_FLOW_DIVERT         0x00800000 /* Flow Divert is enabled */
 #define        SOF_MP_SUBFLOW          0x01000000 /* is a multipath subflow socket */
-#define        SOF_MPTCP_TRUE          0x02000000 /* Established e2e MPTCP connection */
 #define        SOF_MP_SEC_SUBFLOW      0x04000000 /* Set up secondary flow */
 #define        SOF_MP_TRYFAILOVER      0x08000000 /* Failing subflow */
 #define        SOF_DELEGATED           0x10000000 /* on behalf of another process */
index 78f3b6a7fa38a2922f5d3a1cd59a1b99d6cf9b82..be5cfba2e69656d6783fd67aaafe2bd39ac4a45d 100644 (file)
 #define        SIOCSIFNAT64PREFIX      _IOWR('i', 194, struct if_nat64req)
 #endif
 #define        SIOCGIFNEXUS            _IOWR('i', 195, struct if_nexusreq)
-
+#define SIOCGIFPROTOLIST       _IOWR('i', 196, struct if_protolistreq) /* get list of attached protocols */
+#ifdef BSD_KERNEL_PRIVATE
+#define SIOCGIFPROTOLIST32     _IOWR('i', 196, struct if_protolistreq32)
+#define SIOCGIFPROTOLIST64     _IOWR('i', 196, struct if_protolistreq64)
+#endif /* BSD_KERNEL_PRIVATE */
 #endif /* PRIVATE */
 
 #endif /* !_SYS_SOCKIO_H_ */
index 3acef8603bbb5a7e29774f5ec90ffd43b1ff02e7..ff17198ca85dde7be375cd45fb30a2afbbfa7956 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
 
 /*
  * Each subsystem defined by sysctl defines a list of variables
- * for that subsystem. Each name is either a node with further 
+ * for that subsystem. Each name is either a node with further
  * levels defined below it, or it is a leaf of some particular
  * type given below. Each sysctl level defines a set of name/type
  * pairs to be used by sysctl(1) in manipulating the subsystem.
@@ -297,10 +297,10 @@ __END_DECLS
 #define SYSCTL_LINKER_SET_ENTRY(a, b)
 #endif
 /*
- * Macros to define sysctl entries.  Which to use?  Pure data that are 
+ * Macros to define sysctl entries.  Which to use?  Pure data that are
  * returned without modification, SYSCTL_<data type> is for you, like
  * SYSCTL_QUAD for a 64-bit value.  When you want to run a handler of your
- * own, SYSCTL_PROC. 
+ * own, SYSCTL_PROC.
  *
  * parent:     parent in name hierarchy (e.g. _kern for "kern")
  * nbr:                ID.  Almost certainly OID_AUTO ("pick one for me") for you.
@@ -396,7 +396,7 @@ __END_DECLS
                ptr, sizeof(struct type), sysctl_handle_opaque, \
                "S," #type, descr)
 
-/* 
+/*
  * Oid for a procedure.  Specified by a pointer and an arg.
  * CTLTYPE_* macros can determine how the "sysctl" tool deals with
  * input (e.g. converting to int).
@@ -404,8 +404,8 @@ __END_DECLS
 #define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
        SYSCTL_OID(parent, nbr, name, access, \
                ptr, arg, handler, fmt, descr)
-               
-               
+
+
 extern struct sysctl_oid_list sysctl__children;
 SYSCTL_DECL(_kern);
 SYSCTL_DECL(_sysctl);
@@ -418,6 +418,7 @@ SYSCTL_DECL(_machdep);
 SYSCTL_DECL(_user);
 
 #ifdef PRIVATE
+SYSCTL_DECL(_kern_bridge);
 SYSCTL_DECL(_hw_features);
 #endif
 
@@ -565,7 +566,7 @@ SYSCTL_DECL(_hw_features);
  * sysctl(8) to pick up your changes.
  */
 
-#if COUNT_SYSCALLS && defined(KERNEL) 
+#if COUNT_SYSCALLS && defined(KERNEL)
 #define        KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000)        /* keep called count for each bsd syscall */
 #endif
 
@@ -704,7 +705,7 @@ SYSCTL_DECL(_hw_features);
        { "vfsconf", CTLTYPE_STRUCT } \
 }
 
-/* 
+/*
  * KERN_PROC subtypes
  */
 #define KERN_PROC_ALL          0       /* everything */
@@ -716,8 +717,8 @@ SYSCTL_DECL(_hw_features);
 #define        KERN_PROC_RUID          6       /* by real uid */
 #define        KERN_PROC_LCID          7       /* by login context id */
 
-#if defined(XNU_KERNEL_PRIVATE) || !defined(KERNEL) 
-/* 
+#if defined(XNU_KERNEL_PRIVATE) || !defined(KERNEL)
+/*
  * KERN_PROC subtype ops return arrays of augmented proc structures:
  */
 
@@ -772,7 +773,7 @@ struct kinfo_proc {
 #ifdef BSD_KERNEL_PRIVATE
 #include <sys/proc_internal.h>
 
-/* LP64 version of _pcred.  all pointers 
+/* LP64 version of _pcred.  all pointers
  * grow when we're dealing with a 64-bit process.
  * WARNING - keep in sync with _pcred
  */
@@ -796,7 +797,7 @@ struct user64_pcred {
        int     p_refcnt;               /* Number of references. */
 };
 
-/* LP64 version of kinfo_proc.  all pointers 
+/* LP64 version of kinfo_proc.  all pointers
  * grow when we're dealing with a 64-bit process.
  * WARNING - keep in sync with kinfo_proc
  */
@@ -873,7 +874,7 @@ struct user64_kinfo_proc {
 /*
  * Note: "3" was skipped sometime ago and should probably remain unused
  * to avoid any new entry from being accepted by older kernels...
- */ 
+ */
 #define        VM_MACHFACTOR   4               /* struct loadavg with mach factor*/
 #define VM_SWAPUSAGE   5               /* total swap usage */
 #define        VM_MAXID        6               /* number of valid vm ids */
@@ -1036,7 +1037,7 @@ struct user64_loadavg {
  *
  *   hw.packages               - Gives the number of processor packages.
  *
- * These are the selectors for optional processor features for specific processors.  Selectors that return errors are not support 
+ * These are the selectors for optional processor features for specific processors.  Selectors that return errors are not support
  * on the system.  Supported features will return 1 if they are recommended or 0 if they are supported but are not expected to help .
  * performance.  Future versions of these selectors may return larger values as necessary so it is best to test for non zero.
  *
@@ -1053,7 +1054,7 @@ struct user64_loadavg {
  *   hw.optional.dcbtstreams   - Data Cache Block Touch Steams Instruction Form
  *
  * For x86 Architecture:
- * 
+ *
  *   hw.optional.floatingpoint     - Floating Point Instructions
  *   hw.optional.mmx               - Original MMX vector instructions
  *   hw.optional.sse               - Streaming SIMD Extensions
index af3705e2b42bc58831eb616e63b64e6464418efc..48f91cd1b7daf20053d155e1be03b2b7014e4e79 100644 (file)
@@ -230,7 +230,7 @@ void        closelog(void);
 void   openlog(const char *, int, int);
 int    setlogmask(int);
 #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __DARWIN_C_LEVEL >= __DARWIN_C_FULL
-void   syslog(int, const char *, ...) __printflike(2, 3) __not_tail_called __DARWIN_ALIAS_STARTING(__MAC_10_13, __IPHONE_NA, __DARWIN_EXTSN(syslog));
+void   syslog(int, const char *, ...) __DARWIN_ALIAS_STARTING(__MAC_10_13, __IPHONE_NA, __DARWIN_EXTSN(syslog)) __printflike(2, 3) __not_tail_called;
 #else
 void   syslog(int, const char *, ...) __printflike(2, 3) __not_tail_called;
 #endif
index fb2badf23d469ebe02fc901c7a4e671e2238a85e..98dc4dd529f619835e46739441b8dff108ff271b 100644 (file)
@@ -229,6 +229,7 @@ void        throttle_info_release(void *throttle_info);
 void   throttle_info_update(void *throttle_info, int flags);
 uint32_t throttle_lowpri_io(int sleep_amount);
 void   throttle_set_thread_io_policy(int policy);
+int            throttle_get_thread_effective_io_policy(void);
 
 typedef struct __throttle_info_handle *throttle_info_handle_t;
 int    throttle_info_ref_by_mask(uint64_t throttle_mask, throttle_info_handle_t *throttle_info_handle);
index f7e46ec08a6443273aca4b00f2eaffeeb1cd8e75..ae881a0f91d7bc429d1cc75bad64f5f005deba9f 100644 (file)
@@ -115,11 +115,14 @@ __BEGIN_DECLS
 #define WORK_INTERVAL_TYPE_DEFAULT              (0x0 << 28)
 #define WORK_INTERVAL_TYPE_COREAUDIO            (0x1 << 28)
 #define WORK_INTERVAL_TYPE_COREANIMATION        (0x2 << 28)
+#define WORK_INTERVAL_TYPE_CA_RENDER_SERVER     (0x2 << 28)
+#define WORK_INTERVAL_TYPE_CA_CLIENT            (0x3 << 28)
 #define WORK_INTERVAL_TYPE_LAST                 (0xF << 28)
 
 #ifndef KERNEL
 
 typedef struct work_interval *work_interval_t;
+typedef struct work_interval_instance *work_interval_instance_t;
 
 /*
  * Create a new work interval handle.
@@ -150,6 +153,7 @@ typedef struct work_interval *work_interval_t;
  */
 int     work_interval_create(work_interval_t *interval_handle, uint32_t flags);
 
+
 /*
  * Notify the power management subsystem that the work for a current interval has completed
  *
@@ -213,8 +217,6 @@ int     work_interval_join_port(mach_port_t port);
  */
 int     work_interval_leave(void);
 
-/* TODO: complexity measure <rdar://problem/31586510> */
-
 #endif /* !KERNEL */
 
 #if PRIVATE
@@ -242,6 +244,7 @@ struct work_interval_create_params {
        uint32_t        wicp_create_flags;
 };
 
+
 int     __work_interval_ctl(uint32_t operation, uint64_t work_interval_id, void *arg, size_t len);
 
 #endif /* PRIVATE */
index 32fc807ffa48e80960854d24d867781149b70b14..60807acea98e397cb94542a950b99e9c22bb1df4 100644 (file)
@@ -3320,17 +3320,27 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
                if (retval == 0) {
                        int cl_index;
                        int ret_cluster_try_push;
+                       int do_zeroing = 1;
 
-                       io_size += start_offset;
+                       
+                       io_size += start_offset;
+                       
 
-                       if (newEOF >= oldEOF && (upl_f_offset + io_size) >= newEOF && (u_int)io_size < upl_size) {
-                               /*
+                       /* Force more restrictive zeroing behavior only on APFS */
+                       if ((vnode_tag(vp) == VT_APFS) && (newEOF < oldEOF)) {
+                               do_zeroing = 0;
+                       }
+
+
+                       if (do_zeroing && (upl_f_offset + io_size) >= newEOF && (u_int)io_size < upl_size) {
+
+                               /*
                                 * if we're extending the file with this write
                                 * we'll zero fill the rest of the page so that
                                 * if the file gets extended again in such a way as to leave a
                                 * hole starting at this EOF, we'll have zero's in the correct spot
                                 */
-                               cluster_zero(upl, io_size, upl_size - io_size, NULL); 
+                               cluster_zero(upl, io_size, upl_size - io_size, NULL); 
                        }
                        /*
                         * release the upl now if we hold one since...
index d286796231f7ac75ab77e44c92c9fcb2a7ed7504..ff53ee1a3c516d90d16d33c45c89c97b327a41cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2015-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -89,14 +89,40 @@ size_t cpx_sizex(const struct cpx *cpx)
 cpx_t cpx_alloc(size_t key_len)
 {
        cpx_t cpx;
-
+       
+#if TARGET_OS_OSX
+       /* 
+        * Macs only use 1 key per volume, so force it into its own page.
+        * This way, we can write-protect as needed.
+        */
+       size_t cpsize = cpx_size (key_len);
+       if (cpsize < PAGE_SIZE) {
+               MALLOC(cpx, cpx_t, PAGE_SIZE, M_TEMP, M_WAITOK);
+       }
+       else {
+               panic ("cpx_size too large ! (%lu)", cpsize);
+       }
+#else
        MALLOC(cpx, cpx_t, cpx_size(key_len), M_TEMP, M_WAITOK);
-
+#endif
        cpx_init(cpx, key_len);
 
        return cpx;
 }
 
+/* this is really a void function */
+void cpx_writeprotect (cpx_t cpx) 
+{
+#if TARGET_OS_OSX
+       void *cpxstart = (void*)cpx;
+       void *cpxend = (void*)((uint8_t*)cpx + PAGE_SIZE);
+       vm_map_protect (kernel_map, cpxstart, cpxend, (VM_PROT_READ), FALSE);
+#else
+       (void) cpx;
+#endif
+       return;
+}
+
 #if DEBUG
 static const uint32_t cpx_magic1 = 0x7b787063;         // cpx{
 static const uint32_t cpx_magic2 = 0x7870637d;         // }cpx
@@ -104,10 +130,19 @@ static const uint32_t cpx_magic2 = 0x7870637d;            // }cpx
 
 void cpx_free(cpx_t cpx)
 {
+
 #if DEBUG
        assert(cpx->cpx_magic1 == cpx_magic1);
        assert(*PTR_ADD(uint32_t *, cpx, cpx_sizex(cpx) - 4) == cpx_magic2);
 #endif
+       
+#if TARGET_OS_OSX
+       /* unprotect the page before bzeroing */
+       void *cpxstart = (void*)cpx;
+       void *cpxend = (void*)((uint8_t*)cpx + PAGE_SIZE);
+       vm_map_protect (kernel_map, cpxstart, cpxend, (VM_PROT_DEFAULT), FALSE);
+#endif
+
        bzero(cpx->cpx_cached_key, cpx->cpx_max_key_len);
        FREE(cpx, M_TEMP);
 }
index dc434d049f911af08e24c3690b2f00f247a59012..4da9d4535b4b5c90823fe5bd47e02bb533b2b5b0 100644 (file)
@@ -1027,6 +1027,7 @@ vfs_rootmountalloc(const char *fstypename, const char *devname, mount_t *mpp)
        return (ENOMEM);
 }
 
+#define DBG_MOUNTROOT (FSDBG_CODE(DBG_MOUNT, 0))
 
 /*
  * Find an appropriate filesystem to use for the root. If a filesystem
@@ -1049,15 +1050,20 @@ vfs_mountroot(void)
        mount_t mp;
        vnode_t bdevvp_rootvp;
 
+       KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_START);
        if (mountroot != NULL) {
                /*
                 * used for netboot which follows a different set of rules
                 */
                error = (*mountroot)();
+
+               KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error, 0);
                return (error);
        }
        if ((error = bdevvp(rootdev, &rootvp))) {
                printf("vfs_mountroot: can't setup bdevvp\n");
+
+               KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error, 1);
                return (error);
        }
        /*
@@ -1170,8 +1176,10 @@ vfs_mountroot(void)
                        vnode_put(rootvp);
 
 #if CONFIG_MACF
-                       if ((vfs_flags(mp) & MNT_MULTILABEL) == 0)
+                       if ((vfs_flags(mp) & MNT_MULTILABEL) == 0) {
+                               KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, 0, 2);
                                return (0);
+                       }
 
                        error = VFS_ROOT(mp, &vp, ctx);
                        if (error) {
@@ -1193,16 +1201,18 @@ vfs_mountroot(void)
                                goto fail;
                        }
 #endif
+                       KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, 0, 3);
                        return (0);
                }
 #if CONFIG_MACF
 fail:
 #endif
                vfs_rootmountfailed(mp);
-               
+
                if (error != EINVAL)
                        printf("%s_mountroot failed: %d\n", vfsp->vfc_name, error);
        }
+       KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error ? error : ENODEV, 4);
        return (ENODEV);
 }
 
@@ -8782,7 +8792,6 @@ vfs_setcompoundopen(mount_t mp)
        mount_unlock(mp);
 }
 
-
 void
 vnode_setswapmount(vnode_t vp)
 {
index b2209d58d18365621f7e50c14f199abca8e56776..dccc77bd61fddc787e9cffa80600b6c40e86cf55 100644 (file)
        FREE_ZONE((x), MAXPATHLEN, M_NAMEI);
 #endif /* CONFIG_FSE */
 
+#ifndef HFS_GET_BOOT_INFO
+#define HFS_GET_BOOT_INFO   (FCNTL_FS_SPECIFIC_BASE + 0x00004)
+#endif
+
+#ifndef HFS_SET_BOOT_INFO
+#define HFS_SET_BOOT_INFO   (FCNTL_FS_SPECIFIC_BASE + 0x00005)
+#endif
+
+#ifndef APFSIOC_REVERT_TO_SNAPSHOT
+#define APFSIOC_REVERT_TO_SNAPSHOT  _IOW('J', 1, u_int64_t)
+#endif
+
 extern void disk_conditioner_unmount(mount_t mp);
 
 /* struct for checkdirs iteration */
@@ -162,8 +174,8 @@ static int getfsstat_callback(mount_t mp, void * arg);
 static int getutimes(user_addr_t usrtvp, struct timespec *tsp);
 static int setutimes(vfs_context_t ctx, vnode_t vp, const struct timespec *ts, int nullflag);
 static int sync_callback(mount_t, void *);
-static void sync_thread(void *, __unused wait_result_t);
-static int sync_async(int);
+static void hibernate_sync_thread(void *, __unused wait_result_t);
+static int hibernate_sync_async(int);
 static int munge_statfs(struct mount *mp, struct vfsstatfs *sfsp,
                        user_addr_t bufp, int *sizep, boolean_t is_64_bit,
                                                boolean_t partial_copy);
@@ -2313,6 +2325,7 @@ int syncprt = 0;
 int print_vmpage_stat=0;
 int sync_timeout = 60;  // Sync time limit (sec)
 
+
 static int
 sync_callback(mount_t mp, __unused void *arg)
 {
@@ -2346,7 +2359,7 @@ sync(__unused proc_t p, __unused struct sync_args *uap, __unused int32_t *retval
 }
 
 static void
-sync_thread(void *arg, __unused wait_result_t wr)
+hibernate_sync_thread(void *arg, __unused wait_result_t wr)
 {
        int *timeout = (int *) arg;
 
@@ -2368,20 +2381,20 @@ sync_thread(void *arg, __unused wait_result_t wr)
  * Sync in a separate thread so we can time out if it blocks.
  */
 static int
-sync_async(int timeout)
+hibernate_sync_async(int timeout)
 {
        thread_t thd;
        int error;
        struct timespec ts = {timeout, 0};
 
        lck_mtx_lock(sync_mtx_lck);
-       if (kernel_thread_start(sync_thread, &timeout, &thd) != KERN_SUCCESS) {
-               printf("sync_thread failed\n");
+       if (kernel_thread_start(hibernate_sync_thread, &timeout, &thd) != KERN_SUCCESS) {
+               printf("hibernate_sync_thread failed\n");
                lck_mtx_unlock(sync_mtx_lck);
                return (0);
        }
 
-       error = msleep((caddr_t) &timeout, sync_mtx_lck, (PVFS | PDROP | PCATCH), "sync_thread", &ts);
+       error = msleep((caddr_t) &timeout, sync_mtx_lck, (PVFS | PDROP | PCATCH), "hibernate_sync_thread", &ts);
        if (error) {
                printf("sync timed out: %d sec\n", timeout);
        }
@@ -2396,7 +2409,7 @@ sync_async(int timeout)
 __private_extern__ int
 sync_internal(void)
 {
-       (void) sync_async(sync_timeout);
+       (void) hibernate_sync_async(sync_timeout);
 
        return 0;
 } /* end of sync_internal call */
@@ -10444,6 +10457,34 @@ fsctl_internal(proc_t p, vnode_t *arg_vp, u_long cmd, user_addr_t udata, u_long
                break;
 
                default: {
+                       /* other, known commands shouldn't be passed down here */
+                       switch (cmd) {
+                               case F_PUNCHHOLE:
+                               case F_TRIM_ACTIVE_FILE:
+                               case F_RDADVISE:
+                               case F_TRANSCODEKEY:
+                               case F_GETPROTECTIONLEVEL:
+                               case F_GETDEFAULTPROTLEVEL:
+                               case F_MAKECOMPRESSED:
+                               case F_SET_GREEDY_MODE:
+                               case F_SETSTATICCONTENT:
+                               case F_SETIOTYPE:
+                               case F_SETBACKINGSTORE:
+                               case F_GETPATH_MTMINFO:
+                               case APFSIOC_REVERT_TO_SNAPSHOT:
+                               case FSIOC_FIOSEEKHOLE:
+                               case FSIOC_FIOSEEKDATA:
+                               case HFS_GET_BOOT_INFO:
+                               case HFS_SET_BOOT_INFO:
+                               case FIOPINSWAP:
+                               case F_CHKCLEAN:
+                               case F_FULLFSYNC:
+                               case F_BARRIERFSYNC:
+                               case F_FREEZE_FS:
+                               case F_THAW_FS:
+                                       error = EINVAL;
+                                       goto outdrop;
+                       }
                        /* Invoke the filesystem-specific code */
                        error = VNOP_IOCTL(vp, cmd, data, options, ctx);
                }
@@ -10457,6 +10498,7 @@ fsctl_internal(proc_t p, vnode_t *arg_vp, u_long cmd, user_addr_t udata, u_long
        if (error == 0 && (cmd & IOC_OUT) && size)
                error = copyout(data, udata, size);
 
+outdrop:
        if (memp) {
                kfree(memp, size);
        }
@@ -11712,10 +11754,6 @@ snapshot_revert(int dirfd, user_addr_t name, __unused uint32_t flags,
         }
 
 
-#ifndef APFSIOC_REVERT_TO_SNAPSHOT
-#define APFSIOC_REVERT_TO_SNAPSHOT  _IOW('J', 1, u_int64_t)
-#endif
-
         error = VNOP_IOCTL(namend.ni_vp, APFSIOC_REVERT_TO_SNAPSHOT, (caddr_t) NULL,
                            0, ctx);
 
index 8048a6b8022ef4dd63dfdb736b96e88b73e405f7..e94cb60c894c4a4256f5aee913f8aa5f9b80abb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -141,7 +141,32 @@ SYSCTL_PROC(_vm, OID_AUTO, kmem_alloc_contig, CTLTYPE_INT|CTLFLAG_WR|CTLFLAG_LOC
            0, 0, &sysctl_kmem_alloc_contig, "I", "");
 
 extern int vm_region_footprint;
-SYSCTL_INT(_vm, OID_AUTO, region_footprint, CTLFLAG_RW | CTLFLAG_LOCKED, &vm_region_footprint, 0, "");
+SYSCTL_INT(_vm, OID_AUTO, region_footprint, CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED, &vm_region_footprint, 0, "");
+static int
+sysctl_vm_self_region_footprint SYSCTL_HANDLER_ARGS
+{
+#pragma unused(arg1, arg2, oidp)
+       int     error = 0;
+       int     value;
+
+       value = task_self_region_footprint();
+       error = SYSCTL_OUT(req, &value, sizeof (int));
+       if (error) {
+               return error;
+       }
+
+       if (!req->newptr) {
+               return 0;
+       }
+
+       error = SYSCTL_IN(req, &value, sizeof (int));
+       if (error) {
+               return (error);
+       }
+       task_self_region_footprint_set(value);
+       return 0;
+}
+SYSCTL_PROC(_vm, OID_AUTO, self_region_footprint, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY|CTLFLAG_LOCKED|CTLFLAG_MASKED, 0, 0, &sysctl_vm_self_region_footprint, "I", "");
 
 #endif /* DEVELOPMENT || DEBUG */
 
@@ -768,8 +793,9 @@ task_for_pid(
        user_addr_t             task_addr = args->t;
        proc_t                  p = PROC_NULL;
        task_t                  t1 = TASK_NULL;
+       task_t                  task = TASK_NULL;
        mach_port_name_t        tret = MACH_PORT_NULL;
-       ipc_port_t              tfpport;
+       ipc_port_t              tfpport = MACH_PORT_NULL;
        void * sright;
        int error = 0;
 
@@ -807,60 +833,86 @@ task_for_pid(
                goto tfpout;
        }
 
-       if (p->task != TASK_NULL) {
-               /* If we aren't root and target's task access port is set... */
-               if (!kauth_cred_issuser(kauth_cred_get()) &&
-                       p != current_proc() &&
-                       (task_get_task_access_port(p->task, &tfpport) == 0) &&
-                       (tfpport != IPC_PORT_NULL)) {
+       if (p->task == TASK_NULL) {
+               error = KERN_SUCCESS;
+               goto tfpout;
+       }
 
-                       if (tfpport == IPC_PORT_DEAD) {
-                               error = KERN_PROTECTION_FAILURE;
-                               goto tfpout;
-                       }
+#if CONFIG_MACF
+       error = mac_proc_check_get_task(kauth_cred_get(), p);
+       if (error) {
+               error = KERN_FAILURE;
+               goto tfpout;
+       }
+#endif
 
-                       /* Call up to the task access server */
-                       error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport, proc_selfpid(), kauth_getgid(), pid);
+       /* Grab a task reference since the proc ref might be dropped if an upcall to task access server is made */
+       task = p->task;
+       task_reference(task);
 
-                       if (error != MACH_MSG_SUCCESS) {
-                               if (error == MACH_RCV_INTERRUPTED)
-                                       error = KERN_ABORTED;
-                               else
-                                       error = KERN_FAILURE;
-                               goto tfpout;
-                       }
-               }
-#if CONFIG_MACF
-               error = mac_proc_check_get_task(kauth_cred_get(), p);
-               if (error) {
-                       error = KERN_FAILURE;
+       /* If we aren't root and target's task access port is set... */
+       if (!kauth_cred_issuser(kauth_cred_get()) &&
+               p != current_proc() &&
+               (task_get_task_access_port(task, &tfpport) == 0) &&
+               (tfpport != IPC_PORT_NULL)) {
+
+               if (tfpport == IPC_PORT_DEAD) {
+                       error = KERN_PROTECTION_FAILURE;
                        goto tfpout;
                }
-#endif
 
-               /* Grant task port access */
-               task_reference(p->task);
-               extmod_statistics_incr_task_for_pid(p->task);
+               /*
+                * Drop the proc_find proc ref before making an upcall
+                * to taskgated, since holding a proc_find
+                * ref while making an upcall can cause deadlock.
+                */
+               proc_rele(p);
+               p = PROC_NULL;
 
-               sright = (void *) convert_task_to_port(p->task);
+               /* Call up to the task access server */
+               error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport, proc_selfpid(), kauth_getgid(), pid);
 
-               /* Check if the task has been corpsified */
-               if (is_corpsetask(p->task)) {
-                       ipc_port_release_send(sright);
-                       error = KERN_FAILURE;
+               if (error != MACH_MSG_SUCCESS) {
+                       if (error == MACH_RCV_INTERRUPTED)
+                               error = KERN_ABORTED;
+                       else
+                               error = KERN_FAILURE;
                        goto tfpout;
                }
+       }
+
+       /* Grant task port access */
+       extmod_statistics_incr_task_for_pid(task);
+       sright = (void *) convert_task_to_port(task);
+
+       /* Check if the task has been corpsified */
+       if (is_corpsetask(task)) {
+               /* task ref consumed by convert_task_to_port */
+               task = TASK_NULL;
+               ipc_port_release_send(sright);
+               error = KERN_FAILURE;
+               goto tfpout;
+       }
+
+       /* task ref consumed by convert_task_to_port */
+       task = TASK_NULL;
+       tret = ipc_port_copyout_send(
+                       sright,
+                       get_task_ipcspace(current_task()));
 
-               tret = ipc_port_copyout_send(
-                               sright, 
-                               get_task_ipcspace(current_task()));
-       } 
        error = KERN_SUCCESS;
 
 tfpout:
        task_deallocate(t1);
        AUDIT_ARG(mach_port2, tret);
        (void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
+
+       if (tfpport != IPC_PORT_NULL) {
+               ipc_port_release_send(tfpport);
+       }
+       if (task != TASK_NULL) {
+               task_deallocate(task);
+       }
        if (p != PROC_NULL)
                proc_rele(p);
        AUDIT_MACH_SYSCALL_EXIT(error);
@@ -1201,38 +1253,90 @@ out:
 #endif /* CONFIG_EMBEDDED */
 
 #if SOCKETS
+int
+networking_memstatus_callout(proc_t p, uint32_t status)
+{
+       struct filedesc *fdp;
+       int i;
+
+       /*
+        * proc list lock NOT held
+        * proc lock NOT held
+        * a reference on the proc has been held / shall be dropped by the caller.
+        */
+       LCK_MTX_ASSERT(proc_list_mlock, LCK_MTX_ASSERT_NOTOWNED);
+       LCK_MTX_ASSERT(&p->p_mlock, LCK_MTX_ASSERT_NOTOWNED);
+
+       proc_fdlock(p);
+       fdp = p->p_fd;
+       for (i = 0; i < fdp->fd_nfiles; i++) {
+               struct fileproc *fp;
+
+               fp = fdp->fd_ofiles[i];
+               if (fp == NULL || (fdp->fd_ofileflags[i] & UF_RESERVED) != 0) {
+                       continue;
+               }
+               switch (FILEGLOB_DTYPE(fp->f_fglob)) {
+#if NECP
+               case DTYPE_NETPOLICY:
+                       necp_fd_memstatus(p, status,
+                           (struct necp_fd_data *)fp->f_fglob->fg_data);
+                       break;
+#endif /* NECP */
+               default:
+                       break;
+               }
+       }
+       proc_fdunlock(p);
+
+       return (1);
+}
+
+
 static int
-shutdown_sockets_callout(proc_t p, void *arg)
+networking_defunct_callout(proc_t p, void *arg)
 {
        struct pid_shutdown_sockets_args *args = arg;
        int pid = args->pid;
        int level = args->level;
        struct filedesc *fdp;
-       struct fileproc *fp;
        int i;
 
        proc_fdlock(p);
        fdp = p->p_fd;
        for (i = 0; i < fdp->fd_nfiles; i++) {
-               fp = fdp->fd_ofiles[i];
+               struct fileproc *fp = fdp->fd_ofiles[i];
+               struct fileglob *fg;
+
                if (fp == NULL || (fdp->fd_ofileflags[i] & UF_RESERVED) != 0) {
                        continue;
                }
-               if (FILEGLOB_DTYPE(fp->f_fglob) == DTYPE_SOCKET) {
-                       struct socket *so = (struct socket *)fp->f_fglob->fg_data;
+
+               fg = fp->f_fglob;
+               switch (FILEGLOB_DTYPE(fg)) {
+               case DTYPE_SOCKET: {
+                       struct socket *so = (struct socket *)fg->fg_data;
                        if (p->p_pid == pid || so->last_pid == pid || 
                            ((so->so_flags & SOF_DELEGATED) && so->e_pid == pid)) {
                                /* Call networking stack with socket and level */
                                (void) socket_defunct(p, so, level);
                        }
+                       break;
                }
 #if NECP
-               else if (FILEGLOB_DTYPE(fp->f_fglob) == DTYPE_NETPOLICY &&
-                   p->p_pid == pid) {
-                       necp_defunct_client(p, fp);
-               }
+               case DTYPE_NETPOLICY:
+                       /* first pass: defunct necp and get stats for ntstat */
+                       if (p->p_pid == pid) {
+                               necp_fd_defunct(p,
+                                   (struct necp_fd_data *)fg->fg_data);
+                       }
+                       break;
 #endif /* NECP */
+               default:
+                       break;
+               }
        }
+
        proc_fdunlock(p);
 
        return (PROC_RETURNED);
@@ -1271,7 +1375,8 @@ pid_shutdown_sockets(struct proc *p __unused, struct pid_shutdown_sockets_args *
                goto out;
        }
 
-       proc_iterate(PROC_ALLPROCLIST | PROC_NOWAITTRANS, shutdown_sockets_callout, args, NULL, NULL);
+       proc_iterate(PROC_ALLPROCLIST | PROC_NOWAITTRANS,
+           networking_defunct_callout, args, NULL, NULL);
 
 out:
        if (targetproc != PROC_NULL)
index be6ca801337822b398a3025e9c77e80f677e394e..0f0678d3d5920f4c51adee71367c0ad9dee9c394 100644 (file)
@@ -642,6 +642,7 @@ __ZN17IOBigMemoryCursorC2Ev
 __ZN17IOBigMemoryCursorD0Ev
 __ZN17IOBigMemoryCursorD2Ev
 __ZN17IOPolledInterface10gMetaClassE
+__ZN17IOPolledInterface16setEncryptionKeyEPKhm
 __ZN17IOPolledInterfaceC2EPK11OSMetaClass
 __ZN17IOPolledInterfaceD2Ev
 __ZN17IOPowerConnection10gMetaClassE
index d050685e3891512f5c664a3b2939615bf3937b09..1f7734ca8ec605600269b2e8a4b0add69aac9511 100644 (file)
@@ -190,7 +190,6 @@ __ZN16IORangeAllocator9withRangeEyyjj
 __ZN17IOBigMemoryCursor13outputSegmentEN14IOMemoryCursor15PhysicalSegmentEPvj
 __ZN17IOBigMemoryCursor17withSpecificationEyyy
 __ZN17IOBigMemoryCursor21initWithSpecificationEyyy
-__ZN17IOPolledInterface27_RESERVEDIOPolledInterface0Ev
 __ZN17IOPolledInterface27_RESERVEDIOPolledInterface1Ev
 __ZN17IOPolledInterface27_RESERVEDIOPolledInterface2Ev
 __ZN17IOPolledInterface27_RESERVEDIOPolledInterface3Ev
index 6769ed75b3af247b42cba6e69557fc67816e51b7..1737075047b82d20c5bba9f2596b5e962ae5a14a 100644 (file)
@@ -44,9 +44,15 @@ _OSlibkernInit
 _SHA1Final
 _SHA1Init
 _SHA1Update
+_SHA256_Final
+_SHA256_Init
+_SHA256_Update
 _SHA384_Final
 _SHA384_Init
 _SHA384_Update
+_SHA512_Final
+_SHA512_Init
+_SHA512_Update
 _STRDUP
 __Z13OSUnserializePKcPP8OSString
 __Z16OSUnserializeXMLPKcPP8OSString
@@ -709,6 +715,7 @@ _page_shift
 _page_size
 _panic
 _printf
+_random_buf
 _sha1_init:_SHA1Init
 _sha1_loop:_SHA1Update
 _sha1_result:_SHA1Final_r
index b534c3569d8ea443ae858ad4f8dcb63abfa33fed..8deb4e4459e04762e893588e73f11685571bb3de 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Mach Operating System
 # Copyright (c) 1986 Carnegie-Mellon University
-# Copyright 2001-2016 Apple Inc.
+# Copyright 2001-2018 Apple Inc.
 #
 # All rights reserved.  The CMU software License Agreement
 # specifies the terms and conditions for use and redistribution.
 #  FILESYS_DEV =    [ FILESYS_BASE fdesc ]
 #  FILESYS_DEBUG =  [ FILESYS_BASE fdesc ]
 #  NFS =            [ nfsclient nfsserver ]
-#  SKYWALK_BASE =   [ skywalk config_nexus_user_pipe config_nexus_kernel_pipe config_nexus_monitor config_nexus_flowswitch config_nexus_netif ]
-#  SKYWALK_RELEASE = [ SKYWALK_BASE ]
-#  SKYWALK_DEV =    [ SKYWALK_BASE ]
-#  SKYWALK_DEBUG =  [ SKYWALK_BASE ]
 #  NETWORKING =     [ inet tcpdrop_synfin bpfilter inet6 ipv6send if_bridge traffic_mgt dummynet ah_all_crypto if_fake ]
 #  VPN =            [ ipsec flow_divert necp content_filter ]
 #  PF =             [ pf ]
index ae4eb4903f316e40f782b4c9ca9f07d2dcae1d8c..a6636b77362dbf48f584951931d1b4b6ca7afe3d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Mach Operating System
 # Copyright (c) 1986 Carnegie-Mellon University
-# Copyright 2001-2016 Apple Inc.
+# Copyright 2001-2018 Apple Inc.
 #
 # All rights reserved.  The CMU software License Agreement
 # specifies the terms and conditions for use and redistribution.
 #  FILESYS_DEV =    [ FILESYS_BASE fdesc ]
 #  FILESYS_DEBUG =  [ FILESYS_BASE fdesc ]
 #  NFS =            [ nfsclient nfsserver ]
-#  SKYWALK_BASE =   [ skywalk config_nexus_user_pipe config_nexus_kernel_pipe config_nexus_monitor config_nexus_flowswitch config_nexus_netif ]
-#  SKYWALK_RELEASE = [ SKYWALK_BASE ]
-#  SKYWALK_DEV =    [ SKYWALK_BASE ]
-#  SKYWALK_DEBUG =  [ SKYWALK_BASE ]
 #  NETWORKING =     [ inet tcpdrop_synfin bpfilter inet6 ipv6send if_bridge traffic_mgt dummynet ah_all_crypto packet_mangler if_fake ]
 #  VPN =            [ ipsec flow_divert necp content_filter ]
 #  PF =             [ pf ]
index a33253ff58004618278242fd344cfcef5b6f61c1..439e238c67fddc8d6f3bd4c8ecb0f4b7c1c75ff6 100644 (file)
@@ -4,6 +4,7 @@ _assert_wait
 _assert_wait_deadline
 _assert_wait_timeout
 _clock_absolutetime_interval_to_deadline
+_clock_continuoustime_interval_to_deadline
 _clock_delay_until
 _clock_get_calendar_microtime
 _clock_get_calendar_nanotime
index 7efb2c146e628fd35eb4634a83707eb0657309d3..0996d29e78a6882ca6f568280fb2bd0c706264e5 100644 (file)
@@ -1,4 +1,4 @@
-17.4.0
+17.5.0
 
 # The first line of this file contains the master version number for the kernel.
 # All other instances of the kernel version in xnu are derived from this file.
index 5ce2ff9c648b477915d41f0cf6d6cc37da88d39a..5630d2a5082096b53aeabc95df73ee3489db60f2 100644 (file)
@@ -7,6 +7,9 @@ __ZNK18IODTPlatformExpert*
 __ZTV18IODTPlatformExpert
 __ZN5IOCPU*
 __ZNK5IOCPU*
+__ZN12IOUserClient27copyObjectForPortNameInTaskEP4taskjPP8OSObject
+__ZN12IOUserClient27copyPortNameForObjectInTaskEP4taskP8OSObjectPj
+__ZN12IOUserClient30adjustPortNameReferencesInTaskEP4taskji
 __ZTV5IOCPU
 __ZN24IOCPUInterruptController*
 __ZNK24IOCPUInterruptController*
@@ -49,7 +52,6 @@ _bufattr_setcpx
 _bufattr_throttled
 _cdevsw
 _cdevsw_setkqueueok
-_chudxnu_platform_ptr
 _clalloc
 _clfree
 _cluster_unlock_direct_read
@@ -85,6 +87,7 @@ _cpx_size
 _cpx_sizex
 _cpx_use_offset_for_iv
 _cpx_synthetic_offset_for_iv
+_cpx_writeprotect
 _cs_blob_reset_cache
 _cs_debug
 _cs_enforcement
@@ -111,18 +114,22 @@ _csblob_get_teamid
 _csblob_get_signer_type
 _csblob_get_size
 _csfg_get_cdhash
+_csfg_get_identity
 _csfg_get_path
 _csfg_get_platform_binary
+_csfg_get_platform_identifier
 _csfg_get_prod_signed
 _csfg_get_signer_type
 _csfg_get_teamid
 _csproc_get_blob
 _csproc_get_platform_binary
+_csproc_get_platform_identifier
 _csproc_get_prod_signed
 _csproc_get_signer_type
 _csproc_get_teamid
 _csvnode_get_blob
 _csvnode_get_teamid
+_csvnode_get_platform_identifier
 _csvnode_print_debug
 _ctl_enqueuembuf_list
 _ctl_id_by_name
@@ -393,8 +400,10 @@ _thread_call_allocate_with_priority
 _thread_call_allocate_with_qos
 _thread_call_cancel_wait
 _thread_clear_eager_preempt
+_thread_clear_honor_qlimit
 _thread_dispatchqaddr
 _thread_set_eager_preempt
+_thread_set_honor_qlimit
 _thread_set_mach_voucher
 _thread_set_pending_block_hint
 _throttle_info_create
@@ -410,6 +419,7 @@ _throttle_info_update_by_mask
 _throttle_lowpri_io
 _throttle_lowpri_window
 _throttle_set_thread_io_policy
+_throttle_get_thread_effective_io_policy
 _timeout
 _timeout_with_leeway
 _tk_nin
index 5341bdbfefa21d427cf87d4a0fb26b460f727d1e..52902c403eb5f7da46005f5b1d097a569c81a6db 100644 (file)
@@ -1,9 +1,6 @@
 _IOGetBootKeyStoreData
 _IOGetAPFSKeyStoreData
 _IOSetAPFSKeyStoreData
-_SHA256_Final
-_SHA256_Init
-_SHA256_Update
 __ZN14IOPMrootDomain20claimSystemWakeEventEP9IOServicejPKcP8OSObject
 __ZN14IOPMrootDomain20restartWithStackshotEv
 __ZN22IOInterruptEventSource7warmCPUEy
index 6e6f051b931bcffa1939a4f86f860628a5d530e2..4b218498bbb407ea5a21bba72316c3c17b6bb638 100644 (file)
@@ -70,6 +70,7 @@ private:
 
 /*! @var reserved
     Reserved for future use.  (Internal use only)  */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData * reserved;
 
 protected:
@@ -80,6 +81,7 @@ protected:
 private:
     uintptr_t           _internalReserved;
     unsigned             _internalFlags;
+    APPLE_KEXT_WSHADOW_POP;
 
 private:
 #ifndef __LP64__
index 1ee373c3e4c838f14306281d3f67383d6ec74b22..7b1e219c5f37ad3514c255d5c86c0a80be784330 100644 (file)
@@ -66,7 +66,7 @@ protected:
   ipi_handler_t          ipi_handler;
 
   struct ExpansionData { };
-  ExpansionData *reserved;
+  ExpansionData *iocpu_reserved;
 
   virtual void           setCPUNumber(UInt32 cpuNumber);
   virtual void           setCPUState(UInt32 cpuState);
@@ -124,7 +124,7 @@ protected:
   int   numSources;
 
   struct ExpansionData { };
-  ExpansionData *reserved;
+  ExpansionData *iocpuic_reserved;
 
 public:
   virtual IOReturn initCPUInterruptController(int sources);
index ce4851284f2a2ef50674d3a5f0d09385354fd59a..4bc13d299b95d45dac9a7117a85e05f3db9ff3cb 100644 (file)
@@ -91,7 +91,9 @@ protected:
 
 /*! @var reserved
     Reserved for future use.  (Internal use only)  */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData *reserved;
+    APPLE_KEXT_WSHADOW_POP;
 
 public:
 /*! @function commandGate
index 13ef854d8acd97b55cab722c167b37cf33baff0d..3cf68bf1105996830603250b1705189dffae5f80 100644 (file)
@@ -90,7 +90,9 @@ protected:
 
 /*! @var reserved
     Reserved for future use.  (Internal use only)  */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData *reserved;
+    APPLE_KEXT_WSHADOW_POP;
 
 public:
 /*! @function filterInterruptEventSource
index cf8aa46df175e0b1484bed6a87a3265c91bacb76..b6f3b7f62a39822b2d17d7431bdc8b332c97c6b3 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
@@ -54,14 +54,14 @@ struct IOHibernateImageHeader
 {
     uint64_t   imageSize;
     uint64_t   image1Size;
-    
+
     uint32_t   restore1CodePhysPage;
     uint32_t    reserved1;
     uint64_t   restore1CodeVirt;
     uint32_t   restore1PageCount;
     uint32_t   restore1CodeOffset;
     uint32_t   restore1StackOffset;
-    
+
     uint32_t   pageCount;
     uint32_t   bitmapSize;
 
@@ -86,7 +86,7 @@ struct IOHibernateImageHeader
 
     uint32_t    performanceDataStart;
     uint32_t    performanceDataSize;
-    
+
     uint64_t   encryptStart __attribute__ ((packed));
     uint64_t   machineSignature __attribute__ ((packed));
 
@@ -105,7 +105,9 @@ struct IOHibernateImageHeader
     uint32_t   sleepTime;
     uint32_t    compression;
 
-    uint32_t   reserved[58];           // make sizeof == 512
+    uint8_t     bridgeBootSessionUUID[16];
+
+    uint32_t   reserved[54];           // make sizeof == 512
     uint32_t   booterTime0;
     uint32_t   booterTime1;
     uint32_t   booterTime2;
@@ -138,6 +140,7 @@ enum
     kIOHibernateOptionColor         = 0x00000002,
     kIOHibernateOptionProgress      = 0x00000004,
     kIOHibernateOptionDarkWake      = 0x00000008,
+    kIOHibernateOptionHWEncrypt     = 0x00000010,
 };
 
 struct hibernate_bitmap_t
@@ -175,7 +178,7 @@ typedef struct hibernate_cryptvars_t hibernate_cryptvars_t;
 
 #endif /* defined(_AES_H) */
 
-enum 
+enum
 {
     kIOHibernateHandoffType                 = 0x686f0000,
     kIOHibernateHandoffTypeEnd              = kIOHibernateHandoffType + 0,
@@ -185,6 +188,7 @@ enum
     kIOHibernateHandoffTypeDeviceTree       = kIOHibernateHandoffType + 4,
     kIOHibernateHandoffTypeDeviceProperties = kIOHibernateHandoffType + 5,
     kIOHibernateHandoffTypeKeyStore         = kIOHibernateHandoffType + 6,
+    kIOHibernateHandoffTypeVolumeCryptKey   = kIOHibernateHandoffType + 7,
 };
 
 struct IOHibernateHandoff
@@ -195,7 +199,7 @@ struct IOHibernateHandoff
 };
 typedef struct IOHibernateHandoff IOHibernateHandoff;
 
-enum 
+enum
 {
     kIOHibernateProgressCount         = 19,
     kIOHibernateProgressWidth         = 7,
@@ -326,28 +330,28 @@ vm_compressor_do_warmup(void);
 hibernate_page_list_t *
 hibernate_page_list_allocate(boolean_t log);
 
-kern_return_t 
+kern_return_t
 hibernate_alloc_page_lists(
                hibernate_page_list_t ** page_list_ret,
                hibernate_page_list_t ** page_list_wired_ret,
                hibernate_page_list_t ** page_list_pal_ret);
 
-kern_return_t 
+kern_return_t
 hibernate_setup(IOHibernateImageHeader * header,
                         boolean_t vmflush,
                        hibernate_page_list_t * page_list,
                        hibernate_page_list_t * page_list_wired,
                        hibernate_page_list_t * page_list_pal);
 
-kern_return_t 
+kern_return_t
 hibernate_teardown(hibernate_page_list_t * page_list,
                     hibernate_page_list_t * page_list_wired,
                     hibernate_page_list_t * page_list_pal);
 
-kern_return_t 
+kern_return_t
 hibernate_pin_swap(boolean_t begin);
 
-kern_return_t 
+kern_return_t
 hibernate_processor_setup(IOHibernateImageHeader * header);
 
 void
@@ -374,11 +378,11 @@ void
 hibernate_page_list_setall(hibernate_page_list_t * page_list,
                           hibernate_page_list_t * page_list_wired,
                           hibernate_page_list_t * page_list_pal,
-                          boolean_t preflight, 
+                          boolean_t preflight,
                           boolean_t discard_all,
                           uint32_t * pagesOut);
 
-// mark pages to be saved, or pages not to be saved but available 
+// mark pages to be saved, or pages not to be saved but available
 // for scratch usage during restore
 void
 hibernate_page_list_setall_machine(hibernate_page_list_t * page_list,
@@ -402,10 +406,10 @@ void
 hibernate_set_page_state(hibernate_page_list_t * page_list, hibernate_page_list_t * page_list_wired,
                                vm_offset_t ppnum, vm_offset_t count, uint32_t kind);
 
-void 
+void
 hibernate_page_bitset(hibernate_page_list_t * list, boolean_t set, uint32_t page);
 
-boolean_t 
+boolean_t
 hibernate_page_bittst(hibernate_page_list_t * list, uint32_t page);
 
 hibernate_bitmap_t *
@@ -414,7 +418,7 @@ hibernate_page_bitmap_pin(hibernate_page_list_t * list, uint32_t * page);
 uint32_t
 hibernate_page_bitmap_count(hibernate_bitmap_t * bitmap, uint32_t set, uint32_t page);
 
-uintptr_t 
+uintptr_t
 hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags);
 
 void
@@ -428,7 +432,7 @@ hibernate_machine_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4)
 long
 hibernate_kernel_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
 void
-hibernate_newruntime_map(void * map, vm_size_t map_size, 
+hibernate_newruntime_map(void * map, vm_size_t map_size,
                            uint32_t system_table_offset);
 
 
@@ -538,8 +542,8 @@ enum {
 
 enum
 {
-       kIOPreviewImageIndexDesktop = 0, 
-       kIOPreviewImageIndexLockScreen = 1, 
+       kIOPreviewImageIndexDesktop = 0,
+       kIOPreviewImageIndexLockScreen = 1,
        kIOPreviewImageCount = 2
 };
 
@@ -549,7 +553,7 @@ enum
        kIOScreenLockUnlocked        = 2,
        kIOScreenLockLocked          = 3,
        kIOScreenLockFileVaultDialog = 4,
-};     
+};
 
 #define kIOScreenLockStateKey       "IOScreenLockState"
 #define kIOBooterScreenLockStateKey "IOBooterScreenLockState"
index 0a634b056e9397f195b97154a01ab88bc333a489..eca74ce9cb6a9353542fd1119cfb53683c52e033 100644 (file)
@@ -74,7 +74,7 @@ protected:
   IOSimpleLock      *controllerLock;
 
   struct ExpansionData { };
-  ExpansionData *reserved;
+  ExpansionData *ioic_reserved;
 
 public:
   virtual IOReturn registerInterrupt(IOService *nub, int source,
@@ -135,7 +135,7 @@ private:
   bool              sourceIsLevel;
 
   struct ExpansionData { };
-  ExpansionData *reserved;
+  ExpansionData *iosic_reserved __unused;
 
 public:
   virtual IOReturn initInterruptController(IOInterruptController *parentController, OSData *parentSource);
index 693fb800e97fc421143acf882ca30c72d1368fb5..6acde040b62d6ff8bfffea99a56ac55fd41a0b01 100644 (file)
@@ -104,7 +104,9 @@ protected:
 
 /*! @var reserved
     Reserved for future use.  (Internal use only)  */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData *reserved;
+    APPLE_KEXT_WSHADOW_POP;
 
 /*! @function free
     @abstract Sub-class implementation of free method, disconnects from the interrupt source. */
index 146968d7e6c0d08d0f03c05b4cef8570c506b562..5ecf86f08c062a0698f453dbbf34158167529e33 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
@@ -54,6 +54,7 @@
 // IODeviceTree:chosen properties
 #define kIOProgressBackbufferKey                "IOProgressBackbuffer"           /* value is OSData   */
 #define kIOProgressColorThemeKey                "IOProgressColorTheme"           /* value is OSNumber */
+#define kIOBridgeBootSessionUUIDKey             "bridge-boot-session-uuid"       /* value is OSData   */
 
 // interest type
 #define kIOConsoleSecurityInterest             "IOConsoleSecurityInterest"
index 48ff9580d885d129daee873f9884fe0cb19b7298..927ad8cb2f67b748f2071fc7281690c26c4a2c43 100644 (file)
@@ -113,5 +113,83 @@ enum {
     kIOCatalogServiceTerminate
 };
 
+
+#ifdef XNU_KERNEL_PRIVATE
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <kern/ipc_kobject.h>
+
+/*
+ * Functions in iokit:IOUserClient.cpp
+ */
+
+extern void iokit_add_reference( io_object_t obj, ipc_kobject_type_t type );
+
+extern ipc_port_t iokit_port_for_object( io_object_t obj,
+                       ipc_kobject_type_t type );
+
+extern kern_return_t iokit_client_died( io_object_t obj,
+                        ipc_port_t port, ipc_kobject_type_t type, mach_port_mscount_t * mscount );
+
+extern kern_return_t
+iokit_client_memory_for_type(
+       io_object_t     connect,
+       unsigned int    type,
+       unsigned int *  flags,
+       vm_address_t *  address,
+       vm_size_t    *  size );
+
+/*
+ * Functions in osfmk:iokit_rpc.c
+ */
+
+extern ipc_port_t iokit_alloc_object_port( io_object_t obj,
+                       ipc_kobject_type_t type );
+
+extern kern_return_t iokit_destroy_object_port( ipc_port_t port );
+
+extern mach_port_name_t iokit_make_send_right( task_t task,
+                               io_object_t obj, ipc_kobject_type_t type );
+
+extern kern_return_t iokit_mod_send_right( task_t task, mach_port_name_t name, mach_port_delta_t delta );
+
+extern io_object_t iokit_lookup_object_with_port_name(mach_port_name_t name, ipc_kobject_type_t type, task_t task);
+
+extern io_object_t iokit_lookup_connect_ref_current_task(mach_port_name_t name);
+
+extern void iokit_retain_port( ipc_port_t port );
+extern void iokit_release_port( ipc_port_t port );
+extern void iokit_release_port_send( ipc_port_t port );
+
+extern void iokit_lock_port(ipc_port_t port);
+extern void iokit_unlock_port(ipc_port_t port);
+
+extern kern_return_t iokit_switch_object_port( ipc_port_t port, io_object_t obj, ipc_kobject_type_t type );
+
+/*
+ * Functions imported by iokit:IOMemoryDescriptor.cpp
+ */
+
+extern ppnum_t IOGetLastPageNumber(void);
+
+extern kern_return_t IOMapPages(vm_map_t map, mach_vm_address_t va, mach_vm_address_t pa,
+                                 mach_vm_size_t length, unsigned int mapFlags);
+
+extern kern_return_t IOUnmapPages(vm_map_t map, mach_vm_address_t va, mach_vm_size_t length);
+
+extern kern_return_t IOProtectCacheMode(vm_map_t map, mach_vm_address_t va,
+                                       mach_vm_size_t length, unsigned int options);
+
+extern unsigned int IODefaultCacheBits(addr64_t pa);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* MACH_KERNEL_PRIVATE */
+
 #endif /* ! _IOKIT_IOKITSERVER_H */
 
index 31d5e09671d5065e8d58f46261bf5e959447c4ac..b58ea84907fe8601de0089a92f6d0764118e0e40 100644 (file)
@@ -136,6 +136,7 @@ private:
   
   void initNVRAMImage(void);
   void initProxyData(void);
+  IOReturn syncVariables(void);
   
 public:
   virtual bool init(IORegistryEntry *old, const IORegistryPlane *plane) APPLE_KEXT_OVERRIDE;
index 63029bb1d85d5feebed58030559af285ccb10e9d..4f5c8067fd7a4874009be9e1fe0dbb67e9de50c4 100644 (file)
@@ -73,6 +73,14 @@ enum {
 extern int (*PE_halt_restart)(unsigned int type);
 extern int PEHaltRestart(unsigned int type);
 
+#ifdef XNU_KERNEL_PRIVATE
+enum {
+       kIOSystemShutdownNotificationStageProcessExit = 0,
+       kIOSystemShutdownNotificationStageRootUnmount = 1,
+};
+extern void IOSystemShutdownNotification(int stage);
+#endif /* XNU_KERNEL_PRIVATE */
+
 // Save the Panic Info.  Returns the number of bytes saved.
 extern UInt32 PESavePanicInfo(UInt8 *buffer, UInt32 length);
 extern void PESavePanicInfoAction(void *buffer, UInt32 offset, UInt32 length);
@@ -141,7 +149,7 @@ protected:
     int        numInstancesRegistered;
 
     struct ExpansionData { };
-    ExpansionData *reserved;
+    ExpansionData *iope_reserved __unused;
 
     virtual void setBootROMType(long peBootROMType);
     virtual void setChipSetType(long peChipSetType);
@@ -236,7 +244,7 @@ private:
     IODTNVRAM *dtNVRAM;
 
     struct ExpansionData { };
-    ExpansionData *reserved;
+    ExpansionData *iodtpe_reserved;
 
 public:
     virtual IOService * probe( IOService *     provider,
@@ -313,7 +321,7 @@ private:
     IOWorkLoop *workLoop;
 
     struct ExpansionData { };
-    ExpansionData *reserved;
+    ExpansionData *ioped_reserved __unused;
 
 public:
     virtual bool initWithArgs( void * p1, void * p2,
@@ -345,7 +353,7 @@ class IOPlatformDevice : public IOService
     OSDeclareDefaultStructors(IOPlatformDevice)
 
     struct ExpansionData { };
-    ExpansionData *reserved;
+    ExpansionData *iopd_reserved;
 
 public:
     virtual bool compareName( OSString * name, OSString ** matched = 0 ) const APPLE_KEXT_OVERRIDE;
index cd1ba59862f249139c714e78907a62cdc26e01f8..84d27043b03cc749c6142e06843c239bd499d9cf 100644 (file)
@@ -91,7 +91,9 @@ public:
 
     virtual IOReturn checkForWork(void) = 0;
 
-    OSMetaClassDeclareReservedUnused(IOPolledInterface, 0);
+    virtual IOReturn setEncryptionKey(const uint8_t * key, size_t keySize);
+
+    OSMetaClassDeclareReservedUsed(IOPolledInterface, 0);
     OSMetaClassDeclareReservedUnused(IOPolledInterface, 1);
     OSMetaClassDeclareReservedUnused(IOPolledInterface, 2);
     OSMetaClassDeclareReservedUnused(IOPolledInterface, 3);
@@ -177,7 +179,7 @@ IOReturn IOPolledFileOpen(const char * filename,
                          void * write_file_addr, size_t write_file_len,
                          IOPolledFileIOVars ** fileVars,
                          OSData ** imagePath,
-                         uint8_t * volumeCryptKey, size_t keySize);
+                         uint8_t * volumeCryptKey, size_t keySize);
 
 IOReturn IOPolledFileClose(IOPolledFileIOVars ** pVars,
                           off_t write_offset, void * addr, size_t write_length,
@@ -210,6 +212,9 @@ extern __C IOReturn IOPolledFilePollersOpen(IOPolledFileIOVars * vars, uint32_t
 
 extern __C IOReturn IOPolledFilePollersClose(IOPolledFileIOVars * vars, uint32_t state);
 
+extern __C IOReturn IOPolledFilePollersSetEncryptionKey(IOPolledFileIOVars * vars,
+                                   const uint8_t * key, size_t keySize);
+
 extern __C IOPolledFileIOVars * gCoreFileVars;
 
 #ifdef _SYS_CONF_H_
index 89ce8909d48800ef499e9eab00b4c75d112e4e80..20ad4e6abca80b1f4438e27a20bbd4fef06017dc 100644 (file)
@@ -319,7 +319,9 @@ protected:
 
 /*! @var reserved
     Reserved for future use.  (Internal use only)  */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData * reserved;
+    APPLE_KEXT_WSHADOW_POP;
 
 private:
     IOService *     __provider;
index 49b5f257b84403a1661c3fc3838839b14b4a79b6..91ab47cf0293988ce4b5100a388e130ee5df7f66 100644 (file)
@@ -130,7 +130,9 @@ protected:
 
 /*! @var reserved
     Reserved for future use.  (Internal use only)  */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData *reserved;
+    APPLE_KEXT_WSHADOW_POP;
 
 /*! @function timeout
     @abstract Function that routes the call from the OS' timeout mechanism into a work-loop context.
index 2aa05be08b2532d8f9a2173a9073a4c4e2081597..6a714982744917c2a6ff00f165b6a7c68706351a 100644 (file)
@@ -195,7 +195,9 @@ protected:
 /*! @var reserved
     Reserved for future use.  (Internal use only) 
 */
+    APPLE_KEXT_WSHADOW_PUSH;
     ExpansionData * reserved;
+    APPLE_KEXT_WSHADOW_POP;
 
     bool reserve();
 
@@ -386,6 +388,46 @@ public:
     virtual IOReturn exportObjectToClient(task_t task,
                                OSObject *obj, io_object_t *clientObj);
 
+#if KERNEL_PRIVATE
+
+    /*!
+        @function copyPortNameForObjectInTask
+        Make an arbitrary OSObject available to the client task as a port name.
+        The port does not respond to any IOKit IPC calls.
+        @param task The task.
+        @param object The object we want to export to the client.
+        The port holds a reference on the object, this function does not consume any reference on the object.
+        @param port_name Returned value is the task's port name. It has one send right created by this function.
+        @result A return code.
+    */
+    static IOReturn copyPortNameForObjectInTask(task_t task, OSObject *object,
+                       mach_port_name_t * port_name);
+
+    /*!
+        @function copyObjectForPortNameInTask
+        Look up an OSObject given a task's port name created with copyPortNameForObjectInTask().
+        @param task The task.
+        @param port_name The task's port name. This function does not consume any reference on the port name.
+        @param object If the port name is valid, a reference to the object is returned. It should be released by the caller.
+        @result A return code.
+    */
+       static IOReturn copyObjectForPortNameInTask(task_t task, mach_port_name_t port_name,
+                               OSObject **object);
+
+    /*!
+        @function adjustPortNameReferencesInTask
+        Adjust the send rights for a port name created with copyPortNameForObjectInTask().
+        @param task The task.
+        @param port_name The task's port name.
+        @param delta Signed value change to the number of user references.
+        @result A return code.
+    */
+       static IOReturn adjustPortNameReferencesInTask(task_t task, mach_port_name_t port_name, mach_port_delta_t delta);
+
+#define IOUC_COPYPORTNAMEFOROBJECTINTASK    1
+
+#endif /* KERNEL_PRIVATE */
+
     // Old methods for accessing method vector backward compatiblility only
     virtual IOExternalMethod *
         getExternalMethodForIndex( UInt32 index )
index 3fc00ebae61aa3c95b4c97c2b413dd73c7734133..c8393354369ee03fd35e6f1e620c6b129c6b371f 100644 (file)
@@ -614,7 +614,9 @@ enum {
 #define kIOPMPSAdapterDetailsPMUConfigurationKey    "PMUConfiguration"
 #define kIOPMPSAdapterDetailsVoltage            "AdapterVoltage"
 #define kIOPMPSAdapterDetailsSourceIDKey                   "SourceID"
+#define kIOPMPSAdapterDetailsErrorFlagsKey                 "ErrorFlags"
 #define kIOPMPSAdapterDetailsSharedSourceKey           "SharedSource"
+#define kIOPMPSAdapterDetailsCloakedKey                    "CloakedSource"
 
 // values for kIOPSPowerAdapterFamilyKey
 enum {
@@ -636,6 +638,14 @@ enum {
     kIOPSFamilyCodeExternal4     = iokit_family_err(sub_iokit_pmu, 4),
 };
 
+// values for kIOPMPSAdapterDetailsErrorFlagsKey
+enum {
+    kIOPSAdapterErrorFlagNoErrors                     = 0,
+    kIOPSAdapterErrorFlagInsufficientAvailablePower   = (1 << 1),
+    kIOPSAdapterErrorFlagForeignObjectDetected        = (1 << 2),
+    kIOPSAdapterErrorFlagDeviceNeedsToBeRepositioned  = (1 << 3),
+};
+
 // Battery's time remaining estimate is invalid this long (seconds) after a wake
 #define kIOPMPSInvalidWakeSecondsKey           "BatteryInvalidWakeSeconds"
 
index ef5db4353b7d5cff6ccfb5e2d1e4556e77b16b44..fe031ce421bdb3c6270068e1c5fd70aa11baeb02 100644 (file)
@@ -38,7 +38,9 @@ class IOWatchDogTimer : public IOService
 protected:
   IONotifier *notifier;
   struct ExpansionData { };
+  APPLE_KEXT_WSHADOW_PUSH;
   ExpansionData *reserved;
+  APPLE_KEXT_WSHADOW_POP;
   
 public:
   virtual bool start(IOService *provider) APPLE_KEXT_OVERRIDE;
index 1b4f3ce230077843ef0cd032833f92e2196c9c76..532cd57c0b91982a36e8f922f5da584fe09b91c7 100644 (file)
@@ -229,7 +229,7 @@ IOCommandQueue::enqueueCommand(bool gotoSleep,
     /*
      * Make sure that we update the current producer entry before we
      * increment the producer pointer.  This avoids a nasty race as the
-     * as the test for work is producerIndex != consumerIndex and a signal.
+     * test for work is producerIndex != consumerIndex and a signal.
      */
     {
         commandEntryT *q = (commandEntryT *) queue;
index 4ceb8cc0f8d2d3bceaa05713a198106ad4770732..efe918ad42b8cf45cc12a7ba48b7a36257e76a48 100644 (file)
@@ -32,10 +32,10 @@ Sleep:
 
 - PMRootDomain calls IOHibernateSystemSleep() before system sleep
 (devices awake, normal execution context)
-- IOHibernateSystemSleep opens the hibernation file (or partition) at the bsd level, 
+- IOHibernateSystemSleep opens the hibernation file (or partition) at the bsd level,
   grabs its extents and searches for a polling driver willing to work with that IOMedia.
   The BSD code makes an ioctl to the storage driver to get the partition base offset to
-  the disk, and other ioctls to get the transfer constraints 
+  the disk, and other ioctls to get the transfer constraints
   If successful, the file is written to make sure its initially not bootable (in case of
   later failure) and nvram set to point to the first block of the file. (Has to be done
   here so blocking is possible in nvram support).
@@ -45,7 +45,7 @@ Sleep:
   pages for eviction. It also copies processor flags needed for the restore path and sets
   a flag in the boot processor proc info.
   gIOHibernateState = kIOHibernateStateHibernating.
-- Regular sleep progresses - some drivers may inspect the root domain property 
+- Regular sleep progresses - some drivers may inspect the root domain property
   kIOHibernateStateKey to modify behavior. The platform driver saves state to memory
   as usual but leaves motherboard I/O on.
 - Eventually the platform calls ml_ppc_sleep() in the shutdown context on the last cpu,
@@ -57,17 +57,17 @@ Sleep:
   by hibernate_page_list_setall(), avoiding having to find arch dependent low level bits.
   The image header and block list are written. The header includes the second file extent so
   only the header block is needed to read the file, regardless of filesystem.
-  The kernel segment "__HIB" is written uncompressed to the image. This segment of code and data 
+  The kernel segment "__HIB" is written uncompressed to the image. This segment of code and data
   (only) is used to decompress the image during wake/boot.
   Some additional pages are removed from the bitmaps - the buffers used for hibernation.
   The bitmaps are written to the image.
-  More areas are removed from the bitmaps (after they have been written to the image) - the 
+  More areas are removed from the bitmaps (after they have been written to the image) - the
   segment "__HIB" pages and interrupt stack.
-  Each wired page is compressed and written and then each non-wired page. Compression and 
+  Each wired page is compressed and written and then each non-wired page. Compression and
   disk writes are in parallel.
   The image header is written to the start of the file and the polling driver closed.
   The machine powers down (or sleeps).
-  
+
 Boot/Wake:
 
 - BootX sees the boot-image nvram variable containing the device and block number of the image,
@@ -76,8 +76,8 @@ Boot/Wake:
   in the OF memory environment, and the image is decrypted. There is no decompression in BootX,
   that is in the kernel's __HIB section.
 - BootX copies the "__HIB" section to its correct position in memory, quiesces and calls its entry
-  hibernate_kernel_entrypoint(), passing the location of the image in memory. Translation is off, 
-  only code & data in that section is safe to call since all the other wired pages are still 
+  hibernate_kernel_entrypoint(), passing the location of the image in memory. Translation is off,
+  only code & data in that section is safe to call since all the other wired pages are still
   compressed in the image.
 - hibernate_kernel_entrypoint() removes pages occupied by the raw image from the page bitmaps.
   It uses the bitmaps to work out which pages can be uncompressed from the image to their final
@@ -87,11 +87,11 @@ Boot/Wake:
   is used to get pages into place for 64bit.
 - the reset vector is called (at least on ppc), the kernel proceeds on a normal wake, with some
   changes conditional on the per proc flag - before VM is turned on the boot cpu, all mappings
-  are removed from the software strutures, and the hash table is reinitialized. 
+  are removed from the software strutures, and the hash table is reinitialized.
 - After the platform CPU init code is called, hibernate_machine_init() is called to restore the rest
   of memory, using the polled mode driver, before other threads can run or any devices are turned on.
   This reduces the memory usage for BootX and allows decompression in parallel with disk reads,
-  for the remaining non wired pages. 
+  for the remaining non wired pages.
 - The polling driver is closed down and regular wake proceeds. When the kernel calls iokit to wake
   (normal execution context) hibernate_teardown() in osmfk is called to release any memory, the file
   is closed via bsd.
@@ -106,7 +106,7 @@ partition) that the image is going to live, looking for polled interface propert
 one the IOMedia object is passed to a "probe" call for the interface to accept or reject. All the
 interfaces found are kept in an ordered list.
 
-There is an Open/Close pair of calls made to each of the interfaces at various stages since there are 
+There is an Open/Close pair of calls made to each of the interfaces at various stages since there are
 few different contexts things happen in:
 
 - there is an Open/Close (Preflight) made before any part of the system has slept (I/O is all
@@ -116,7 +116,7 @@ immediately wakes back up for the image write.
 
 - there is an Open/Close (BeforeSleep) pair made around the image write operations that happen
 immediately before sleep. These can't block or allocate memory - the I/O system is asleep apart
-from the low level bits (motherboard I/O etc). There is only one thread running. The close can be 
+from the low level bits (motherboard I/O etc). There is only one thread running. The close can be
 used to flush and set the disk to sleep.
 
 - there is an Open/Close (AfterSleep) pair made around the image read operations that happen
@@ -146,6 +146,7 @@ to restrict I/O ops.
 #include <IOKit/IOMessage.h>
 #include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/IOBSD.h>
+#include <IOKit/IOKitKeysPrivate.h>
 #include "RootDomainUserClient.h"
 #include <IOKit/pwr_mgt/IOPowerConnection.h>
 #include "IOPMPowerStateQueue.h"
@@ -189,6 +190,9 @@ extern uint32_t             gIOHibernateState;
 uint32_t                       gIOHibernateMode;
 static char                    gIOHibernateBootSignature[256+1];
 static char                    gIOHibernateFilename[MAXPATHLEN+1];
+
+static uuid_string_t           gIOHibernateBridgeBootSessionUUIDString;
+
 static uint32_t                        gIOHibernateFreeRatio = 0;       // free page target (percent)
 uint32_t                       gIOHibernateFreeTime  = 0*1000;  // max time to spend freeing pages (ms)
 static uint64_t                        gIOHibernateCompression = 0x80;  // default compression 50%
@@ -198,6 +202,8 @@ static IODTNVRAM *          gIOOptionsEntry;
 static IORegistryEntry *       gIOChosenEntry;
 
 static const OSSymbol *        gIOHibernateBootImageKey;
+static const OSSymbol *        gIOHibernateBootSignatureKey;
+static const OSSymbol *        gIOBridgeBootSessionUUIDKey;
 
 #if defined(__i386__) || defined(__x86_64__)
 
@@ -224,7 +230,7 @@ static hibernate_graphics_t *                 gIOHibernateGraphicsInfo = &_hibernateGraphics
 static hibernate_statistics_t            _hibernateStats;
 static hibernate_statistics_t *                  gIOHibernateStats = &_hibernateStats;
 
-enum 
+enum
 {
     kFSIdle      = 0,
     kFSOpening   = 2,
@@ -410,7 +416,7 @@ IOHibernateSystemSleep(void)
     {
         if (kIOHibernateModeSleep & gIOHibernateMode)
             // default to discard clean for safe sleep
-            gIOHibernateMode ^= (kIOHibernateModeDiscardCleanInactive 
+            gIOHibernateMode ^= (kIOHibernateModeDiscardCleanInactive
                                 | kIOHibernateModeDiscardCleanActive);
     }
 
@@ -454,7 +460,7 @@ IOHibernateSystemSleep(void)
         vars->srcBuffer = IOBufferMemoryDescriptor::withOptions(kIODirectionOutIn,
                                    2 * page_size + WKdm_SCRATCH_BUF_SIZE_INTERNAL, page_size);
 
-       vars->handoffBuffer = IOBufferMemoryDescriptor::withOptions(kIODirectionOutIn, 
+       vars->handoffBuffer = IOBufferMemoryDescriptor::withOptions(kIODirectionOutIn,
                                    ptoa_64(gIOHibernateHandoffPageCount), page_size);
 
         if (!vars->srcBuffer || !vars->handoffBuffer)
@@ -484,7 +490,7 @@ IOHibernateSystemSleep(void)
        gIOHibernateCurrentHeader->signature = kIOHibernateHeaderInvalidSignature;
 
        vmflush = ((kOSBooleanTrue == IOService::getPMRootDomain()->getProperty(kIOPMDeepSleepEnabledKey)));
-        err = hibernate_alloc_page_lists(&vars->page_list, 
+        err = hibernate_alloc_page_lists(&vars->page_list,
                                         &vars->page_list_wired,
                                         &vars->page_list_pal);
         if (KERN_SUCCESS != err) break;
@@ -512,18 +518,18 @@ IOHibernateSystemSleep(void)
                                + (consoleInfo.v_width * consoleInfo.v_height * 8);
            enum { setFileRound = 1024*1024ULL };
            setFileSize = ((setFileSize + setFileRound) & ~(setFileRound - 1));
-       
-           HIBLOG("hibernate_page_list_setall preflight pageCount %d est comp %qd setfile %qd min %qd\n", 
+
+           HIBLOG("hibernate_page_list_setall preflight pageCount %d est comp %qd setfile %qd min %qd\n",
                    pageCount, (100ULL * gIOHibernateCompression) >> 8,
                    setFileSize, vars->fileMinSize);
 
            if (!(kIOHibernateModeFileResize & gIOHibernateMode)
             && (setFileSize < vars->fileMinSize))
-           { 
+           {
                setFileSize = vars->fileMinSize;
            }
        }
-    
+
        // Invalidate the image file
     if (gDebugImageLock) {
         IOLockLock(gDebugImageLock);
@@ -534,10 +540,11 @@ IOHibernateSystemSleep(void)
         IOLockUnlock(gDebugImageLock);
     }
 
+        vars->volumeCryptKeySize = sizeof(vars->volumeCryptKey);
         err = IOPolledFileOpen(gIOHibernateFilename, setFileSize, 0,
                                gIOHibernateCurrentHeader, sizeof(gIOHibernateCurrentHeader),
-                                &vars->fileVars, &nvramData, 
-                                &vars->volumeCryptKey[0], sizeof(vars->volumeCryptKey));
+                                &vars->fileVars, &nvramData,
+                                &vars->volumeCryptKey[0], &vars->volumeCryptKeySize);
 
         if (KERN_SUCCESS != err)
         {
@@ -559,7 +566,7 @@ IOHibernateSystemSleep(void)
         if (KERN_SUCCESS != err) break;
 
         clock_get_uptime(&startTime);
-        err = hibernate_setup(gIOHibernateCurrentHeader, 
+        err = hibernate_setup(gIOHibernateCurrentHeader,
                                 vmflush,
                                 vars->page_list, vars->page_list_wired, vars->page_list_pal);
         clock_get_uptime(&endTime);
@@ -586,11 +593,11 @@ IOHibernateSystemSleep(void)
 
 
 #if defined(__i386__) || defined(__x86_64__)
-       if (!uuid_is_null(vars->volumeCryptKey) &&
+       if (vars->volumeCryptKeySize &&
              (kOSBooleanTrue != IOService::getPMRootDomain()->getProperty(kIOPMDestroyFVKeyOnStandbyKey)))
        {
            uintptr_t smcVars[2];
-           smcVars[0] = sizeof(vars->volumeCryptKey);
+           smcVars[0] = vars->volumeCryptKeySize;
            smcVars[1] = (uintptr_t)(void *) &gIOHibernateVars.volumeCryptKey[0];
 
            IOService::getPMRootDomain()->setProperty(kIOHibernateSMCVariablesKey, smcVars, sizeof(smcVars));
@@ -599,8 +606,8 @@ IOHibernateSystemSleep(void)
 #endif
 
 
-        if (encryptedswap || !uuid_is_null(vars->volumeCryptKey))
-            gIOHibernateMode ^= kIOHibernateModeEncrypt; 
+        if (encryptedswap || vars->volumeCryptKeySize)
+            gIOHibernateMode ^= kIOHibernateModeEncrypt;
 
         if (kIOHibernateOptionProgress & gIOHibernateCurrentHeader->options)
         {
@@ -640,7 +647,7 @@ IOHibernateSystemSleep(void)
            bcopy(&vars->wiredCryptKey[0], &rtcVars.wiredCryptKey[0], sizeof(rtcVars.wiredCryptKey));
 
             if (gIOChosenEntry
-               && (data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(kIOHibernateBootSignatureKey)))
+               && (data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(gIOHibernateBootSignatureKey)))
                && (sizeof(rtcVars.booterSignature) <= data->getLength()))
            {
                bcopy(data->getBytesNoCopy(), &rtcVars.booterSignature[0], sizeof(rtcVars.booterSignature));
@@ -673,7 +680,7 @@ IOHibernateSystemSleep(void)
            }
            data = OSData::withBytes(&rtcVars, sizeof(rtcVars));
            if (data)
-           { 
+           {
                if (gIOHibernateRTCVariablesKey)
                    IOService::getPMRootDomain()->setProperty(gIOHibernateRTCVariablesKey, data);
                data->release();
@@ -687,7 +694,7 @@ IOHibernateSystemSleep(void)
                {
                    OSData * fileData = 0;
                    data = OSDynamicCast(OSData, gIOChosenEntry->getProperty("boot-device-path"));
-                   if (data->getLength() >= 4) fileData = OSDynamicCast(OSData, gIOChosenEntry->getProperty("boot-file-path"));
+                   if (data && data->getLength() >= 4) fileData = OSDynamicCast(OSData, gIOChosenEntry->getProperty("boot-file-path"));
                    if (data)
                    {
                        // AppleNVRAM_EFI_LOAD_OPTION
@@ -799,7 +806,7 @@ IOSetBootImageNVRAM(OSData * data)
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/* 
+/*
  * Writes header to disk with signature, block size and file extents data.
  * If there are more than 2 extents, then they are written on second block.
  */
@@ -830,14 +837,14 @@ IOWriteExtentsToFile(IOPolledFileIOVars * vars, uint32_t signature)
     if (hdr.fileExtentMapSize > sizeof(hdr.fileExtentMap))
     {
             count = hdr.fileExtentMapSize - sizeof(hdr.fileExtentMap);
-            rc = kern_write_file(vars->fileRef, vars->blockSize, 
-                                 (caddr_t)(((uint8_t *)fileExtents) + sizeof(hdr.fileExtentMap)), 
+            rc = kern_write_file(vars->fileRef, vars->blockSize,
+                                 (caddr_t)(((uint8_t *)fileExtents) + sizeof(hdr.fileExtentMap)),
                                  count, IO_SKIP_ENCRYPTION);
             if (rc != 0) {
                 HIBLOG("kern_write_file returned %d\n", rc);
                 err = kIOReturnIOError;
                 goto exit;
-            }    
+            }
     }
     hdr.signature = signature;
     hdr.deviceBlockSize = vars->blockSize;
@@ -939,11 +946,11 @@ ProgressInit(hibernate_graphics_t * display, uint8_t * screen, uint8_t * saveund
     rowBytes = display->rowBytes;
     pixelShift = display->depth >> 4;
     if (pixelShift < 1) return;
-    
+
     screen += ((display->width
                 - kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))
         + (display->height - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;
-    
+
     for (y = 0; y < kIOHibernateProgressHeight; y++)
     {
         out = screen + y * rowBytes;
@@ -1000,7 +1007,7 @@ ProgressUpdate(hibernate_graphics_t * display, uint8_t * screen, int32_t firstBl
 
     rowBytes = display->rowBytes;
 
-    screen += ((display->width 
+    screen += ((display->width
             - kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))
                 + (display->height - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;
 
@@ -1088,8 +1095,8 @@ IOHibernateSystemHasSlept(void)
     }
 
     if ((kIOHibernateOptionProgress & gIOHibernateCurrentHeader->options)
-        && vars->previewBuffer 
-        && (data = OSDynamicCast(OSData, 
+        && vars->previewBuffer
+        && (data = OSDynamicCast(OSData,
        IOService::getPMRootDomain()->getProperty(kIOHibernatePreviewActiveKey))))
     {
        UInt32 flags = *((UInt32 *)data->getBytesNoCopy());
@@ -1111,7 +1118,7 @@ IOHibernateSystemHasSlept(void)
            vars->consoleMapping   = (uint8_t *) consoleInfo.v_baseAddr;
 
            HIBPRINT("video %p %d %d %d\n",
-                       vars->consoleMapping, graphicsInfo->depth, 
+                       vars->consoleMapping, graphicsInfo->depth,
                        graphicsInfo->width, graphicsInfo->height);
            if (vars->consoleMapping)
                        ProgressInit(graphicsInfo, vars->consoleMapping,
@@ -1178,6 +1185,9 @@ IOHibernateSystemWake(void)
 static IOReturn
 IOHibernateDone(IOHibernateVars * vars)
 {
+    IOReturn err;
+    OSData * data;
+
     hibernate_teardown(vars->page_list, vars->page_list_wired, vars->page_list_pal);
 
     if (vars->videoMapping)
@@ -1198,7 +1208,7 @@ IOHibernateDone(IOHibernateVars * vars)
 
     if (kIOHibernateStateWakingFromHibernate == gIOHibernateState)
     {
-        IOService::getPMRootDomain()->setProperty(kIOHibernateOptionsKey, 
+        IOService::getPMRootDomain()->setProperty(kIOHibernateOptionsKey,
                                             gIOHibernateCurrentHeader->options, 32);
     }
     else
@@ -1209,7 +1219,7 @@ IOHibernateDone(IOHibernateVars * vars)
     if ((kIOHibernateStateWakingFromHibernate == gIOHibernateState)
       && (kIOHibernateGfxStatusUnknown != gIOHibernateGraphicsInfo->gfxStatus))
     {
-        IOService::getPMRootDomain()->setProperty(kIOHibernateGfxStatusKey, 
+        IOService::getPMRootDomain()->setProperty(kIOHibernateGfxStatusKey,
                                         &gIOHibernateGraphicsInfo->gfxStatus,
                                         sizeof(gIOHibernateGraphicsInfo->gfxStatus));
     }
@@ -1274,7 +1284,7 @@ IOHibernateDone(IOHibernateVars * vars)
                    case kIOHibernateHandoffTypeDeviceTree:
                        MergeDeviceTree((DeviceTreeNode *) data, IOService::getServiceRoot());
                        break;
-       
+
                    case kIOHibernateHandoffTypeKeyStore:
 #if defined(__i386__) || defined(__x86_64__)
                        {
@@ -1287,16 +1297,42 @@ IOHibernateDone(IOHibernateVars * vars)
                        }
 #endif
                        break;
-       
+
                    default:
                        done = (kIOHibernateHandoffType != (handoff->type & 0xFFFF0000));
                        break;
-               }    
+               }
            }
+#if defined(__i386__) || defined(__x86_64__)
+           if (vars->volumeCryptKeySize)
+           {
+               IOBufferMemoryDescriptor *
+               bmd = IOBufferMemoryDescriptor::withBytes(&vars->volumeCryptKey[0],
+                           vars->volumeCryptKeySize, kIODirectionOutIn);
+               if (!bmd) panic("IOBufferMemoryDescriptor");
+               IOSetAPFSKeyStoreData(bmd);
+               bzero(&vars->volumeCryptKey[0], sizeof(vars->volumeCryptKey));
+           }
+#endif
+
        }
        vars->handoffBuffer->release();
     }
 
+    if (gIOChosenEntry
+        && (data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(gIOBridgeBootSessionUUIDKey)))
+        && (sizeof(gIOHibernateBridgeBootSessionUUIDString) <= data->getLength()))
+    {
+        bcopy(data->getBytesNoCopy(), &gIOHibernateBridgeBootSessionUUIDString[0],
+                sizeof(gIOHibernateBridgeBootSessionUUIDString));
+    }
+
+    if (vars->hwEncrypt)
+    {
+        err = IOPolledFilePollersSetEncryptionKey(vars->fileVars, NULL, 0);
+        HIBLOG("IOPolledFilePollersSetEncryptionKey(0,%x)\n", err);
+    }
+
     bzero(vars, sizeof(*vars));
 
 //    gIOHibernateState = kIOHibernateStateInactive;       // leave it for post wake code to see
@@ -1375,18 +1411,21 @@ uint32_t IOHibernateWasScreenLocked(void)
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-SYSCTL_STRING(_kern, OID_AUTO, hibernatefile, 
+SYSCTL_STRING(_kern, OID_AUTO, hibernatefile,
                CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
                gIOHibernateFilename, sizeof(gIOHibernateFilename), "");
-SYSCTL_STRING(_kern, OID_AUTO, bootsignature, 
+SYSCTL_STRING(_kern, OID_AUTO, bootsignature,
                CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
                gIOHibernateBootSignature, sizeof(gIOHibernateBootSignature), "");
-SYSCTL_UINT(_kern, OID_AUTO, hibernatemode, 
+SYSCTL_UINT(_kern, OID_AUTO, hibernatemode,
                CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
                &gIOHibernateMode, 0, "");
 SYSCTL_STRUCT(_kern, OID_AUTO, hibernatestatistics,
                CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
                &_hibernateStats, hibernate_statistics_t, "");
+SYSCTL_STRING(_kern_bridge, OID_AUTO, bootsessionuuid,
+               CTLFLAG_RD | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
+               gIOHibernateBridgeBootSessionUUIDString, sizeof(gIOHibernateBridgeBootSessionUUIDString), "");
 
 SYSCTL_UINT(_kern, OID_AUTO, hibernategraphicsready,
                CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_ANYBODY,
@@ -1401,11 +1440,12 @@ SYSCTL_UINT(_kern, OID_AUTO, hibernatehidready,
                CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_ANYBODY,
                &_hibernateStats.hidReadyTime, 0, "");
 
-
 void
 IOHibernateSystemInit(IOPMrootDomain * rootDomain)
 {
-    gIOHibernateBootImageKey = OSSymbol::withCStringNoCopy(kIOHibernateBootImageKey);
+    gIOHibernateBootImageKey     = OSSymbol::withCStringNoCopy(kIOHibernateBootImageKey);
+    gIOHibernateBootSignatureKey = OSSymbol::withCStringNoCopy(kIOHibernateBootSignatureKey);
+    gIOBridgeBootSessionUUIDKey  = OSSymbol::withCStringNoCopy(kIOBridgeBootSessionUUIDKey);
 
 #if defined(__i386__) || defined(__x86_64__)
     gIOHibernateRTCVariablesKey = OSSymbol::withCStringNoCopy(kIOHibernateRTCVariablesKey);
@@ -1437,12 +1477,20 @@ IOHibernateSystemInit(IOPMrootDomain * rootDomain)
 
     gIOChosenEntry = IORegistryEntry::fromPath("/chosen", gIODTPlane);
 
+    if (gIOChosenEntry
+        && (data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(gIOBridgeBootSessionUUIDKey)))
+        && (sizeof(gIOHibernateBridgeBootSessionUUIDString) <= data->getLength()))
+    {
+        sysctl_register_oid(&sysctl__kern_bridge_bootsessionuuid);
+        bcopy(data->getBytesNoCopy(), &gIOHibernateBridgeBootSessionUUIDString[0], sizeof(gIOHibernateBridgeBootSessionUUIDString));
+    }
+
     gFSLock = IOLockAlloc();
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-static IOReturn 
+static IOReturn
 IOHibernatePolledFileWrite(IOPolledFileIOVars * vars,
                           const uint8_t * bytes, IOByteCount size,
                           IOPolledFileCryptVars * cryptvars)
@@ -1531,7 +1579,7 @@ hibernate_write_image(void)
         static const unsigned char first_iv[AES_BLOCK_SIZE]
         = {  0xa3, 0x63, 0x65, 0xa9, 0x0b, 0x71, 0x7b, 0x1c,
              0xdf, 0x9e, 0x5f, 0x32, 0xd7, 0x61, 0x63, 0xda };
-    
+
         cryptvars = &gIOHibernateCryptWakeContext;
         bzero(cryptvars, sizeof(IOPolledFileCryptVars));
         aes_encrypt_key(vars->cryptKey,
@@ -1545,7 +1593,6 @@ hibernate_write_image(void)
         bzero(cryptvars, sizeof(IOPolledFileCryptVars));
         for (pageCount = 0; pageCount < sizeof(vars->wiredCryptKey); pageCount++)
             vars->wiredCryptKey[pageCount] ^= vars->volumeCryptKey[pageCount];
-        bzero(&vars->volumeCryptKey[0], sizeof(vars->volumeCryptKey));
         aes_encrypt_key(vars->wiredCryptKey,
                         kIOHibernateAESKeySize,
                         &cryptvars->ctx.encrypt);
@@ -1561,7 +1608,7 @@ hibernate_write_image(void)
                                vars->page_list_pal,
                               false /* !preflight */,
                               /* discard_all */
-                              ((0 == (kIOHibernateModeSleep & gIOHibernateMode)) 
+                              ((0 == (kIOHibernateModeSleep & gIOHibernateMode))
                               && (0 != ((kIOHibernateModeDiscardCleanActive | kIOHibernateModeDiscardCleanInactive) & gIOHibernateMode))),
                                &pageCount);
 
@@ -1573,7 +1620,7 @@ hibernate_write_image(void)
     count = vars->fileExtents->getLength() / sizeof(IOPolledFileExtent);
     for (page = 0; page < count; page++)
     {
-       HIBLOG("fileExtents[%d] %qx, %qx (%qx)\n", page, 
+       HIBLOG("fileExtents[%d] %qx, %qx (%qx)\n", page,
                fileExtents[page].start, fileExtents[page].length,
                fileExtents[page].start + fileExtents[page].length);
     }
@@ -1584,9 +1631,9 @@ hibernate_write_image(void)
     compBytes = 0;
 
     clock_get_uptime(&allTime);
-    IOService::getPMRootDomain()->pmStatsRecordEvent( 
+    IOService::getPMRootDomain()->pmStatsRecordEvent(
                         kIOPMStatsHibernateImageWrite | kIOPMStatsEventStartFlag, allTime);
-    do 
+    do
     {
         compressedSize   = 0;
         uncompressedSize = 0;
@@ -1594,8 +1641,8 @@ hibernate_write_image(void)
         zvPageCount      = 0;
 
         IOPolledFileSeek(vars->fileVars, vars->fileVars->blockSize);
-    
-        HIBLOG("IOHibernatePollerOpen, ml_get_interrupts_enabled %d\n", 
+
+        HIBLOG("IOHibernatePollerOpen, ml_get_interrupts_enabled %d\n",
                 ml_get_interrupts_enabled());
         err = IOPolledFilePollersOpen(vars->fileVars, kIOPolledBeforeSleepState,
                 // abortable if not low battery
@@ -1604,9 +1651,18 @@ hibernate_write_image(void)
         pollerOpen = (kIOReturnSuccess == err);
         if (!pollerOpen)
             break;
-    
+
+       if (vars->volumeCryptKeySize)
+       {
+           err = IOPolledFilePollersSetEncryptionKey(vars->fileVars, &vars->volumeCryptKey[0], vars->volumeCryptKeySize);
+           HIBLOG("IOPolledFilePollersSetEncryptionKey(%x)\n", err);
+           vars->hwEncrypt = (kIOReturnSuccess == err);
+           bzero(&vars->volumeCryptKey[0], sizeof(vars->volumeCryptKey));
+           if (vars->hwEncrypt) header->options |= kIOHibernateOptionHWEncrypt;
+       }
+
         // copy file block extent list if larger than header
-    
+
         count = vars->fileVars->fileExtents->getLength();
         if (count > sizeof(header->fileExtentMap))
         {
@@ -1640,6 +1696,11 @@ hibernate_write_image(void)
         header->restore1CodeOffset = ((uintptr_t) &hibernate_machine_entrypoint)      - hibernateBase;
         header->restore1StackOffset = ((uintptr_t) &gIOHibernateRestoreStackEnd[0]) - 64 - hibernateBase;
 
+        if (uuid_parse(&gIOHibernateBridgeBootSessionUUIDString[0], &header->bridgeBootSessionUUID[0]))
+        {
+            bzero(&header->bridgeBootSessionUUID[0], sizeof(header->bridgeBootSessionUUID));
+        }
+
         // sum __HIB seg, with zeros for the stack
         src = (uint8_t *) trunc_page(hibernateBase);
         for (page = 0; page < count; page++)
@@ -1651,7 +1712,7 @@ hibernate_write_image(void)
             src += page_size;
         }
         sum1 = restore1Sum;
-    
+
         // write the __HIB seg, with zeros for the stack
 
         src = (uint8_t *) trunc_page(hibernateBase);
@@ -1662,7 +1723,7 @@ hibernate_write_image(void)
             if (kIOReturnSuccess != err)
                 break;
         }
-        err = IOHibernatePolledFileWrite(vars->fileVars, 
+        err = IOHibernatePolledFileWrite(vars->fileVars,
                                         (uint8_t *) 0,
                                         &gIOHibernateRestoreStackEnd[0] - &gIOHibernateRestoreStack[0],
                                         cryptvars);
@@ -1677,7 +1738,7 @@ hibernate_write_image(void)
                 break;
         }
 
-       if (kIOHibernateModeEncrypt & gIOHibernateMode)
+       if (!vars->hwEncrypt && (kIOHibernateModeEncrypt & gIOHibernateMode))
        {
            vars->fileVars->encryptStart = (vars->fileVars->position & ~(AES_BLOCK_SIZE - 1));
            vars->fileVars->encryptEnd   = UINT64_MAX;
@@ -1695,8 +1756,8 @@ hibernate_write_image(void)
                 phys64 = vars->previewBuffer->getPhysicalSegment(count, &segLen, kIOMemoryMapperNone);
                 pageAndCount[0] = atop_64(phys64);
                 pageAndCount[1] = atop_32(segLen);
-                err = IOHibernatePolledFileWrite(vars->fileVars, 
-                                        (const uint8_t *) &pageAndCount, sizeof(pageAndCount), 
+                err = IOHibernatePolledFileWrite(vars->fileVars,
+                                        (const uint8_t *) &pageAndCount, sizeof(pageAndCount),
                                         cryptvars);
                 if (kIOReturnSuccess != err)
                     break;
@@ -1733,35 +1794,35 @@ hibernate_write_image(void)
             (phys64 = ioBuffer->getPhysicalSegment(count, &segLen, kIOMemoryMapperNone));
             count += segLen)
         {
-            hibernate_set_page_state(vars->page_list, vars->page_list_wired, 
+            hibernate_set_page_state(vars->page_list, vars->page_list_wired,
                                         atop_64(phys64), atop_32(segLen),
                                         kIOHibernatePageStateFree);
             pageCount -= atop_32(segLen);
         }
-    
+
         for (count = 0;
             (phys64 = vars->srcBuffer->getPhysicalSegment(count, &segLen, kIOMemoryMapperNone));
             count += segLen)
         {
-            hibernate_set_page_state(vars->page_list, vars->page_list_wired, 
+            hibernate_set_page_state(vars->page_list, vars->page_list_wired,
                                         atop_64(phys64), atop_32(segLen),
                                         kIOHibernatePageStateFree);
             pageCount -= atop_32(segLen);
         }
 
         // copy out bitmap of pages available for trashing during restore
-    
+
         bitmap_size = vars->page_list_wired->list_size;
         src = (uint8_t *) vars->page_list_wired;
         err = IOHibernatePolledFileWrite(vars->fileVars, src, bitmap_size, cryptvars);
         if (kIOReturnSuccess != err)
             break;
 
-        // mark more areas for no save, but these are not available 
+        // mark more areas for no save, but these are not available
         // for trashing during restore
 
        hibernate_page_list_set_volatile(vars->page_list, vars->page_list_wired, &pageCount);
-    
+
 
         page = atop_32(KERNEL_IMAGE_TO_PHYS(hibernateBase));
         count = atop_32(round_page(KERNEL_IMAGE_TO_PHYS(hibernateEnd))) - page;
@@ -1774,7 +1835,7 @@ hibernate_write_image(void)
                                         (phys64 = vars->previewBuffer->getPhysicalSegment(count, &segLen, kIOMemoryMapperNone));
                                         count += segLen)
         {
-            hibernate_set_page_state(vars->page_list, vars->page_list_wired, 
+            hibernate_set_page_state(vars->page_list, vars->page_list_wired,
                                         atop_64(phys64), atop_32(segLen),
                                         kIOHibernatePageStateFree);
             pageCount -= atop_32(segLen);
@@ -1784,7 +1845,7 @@ hibernate_write_image(void)
             (phys64 = vars->handoffBuffer->getPhysicalSegment(count, &segLen, kIOMemoryMapperNone));
             count += segLen)
         {
-            hibernate_set_page_state(vars->page_list, vars->page_list_wired, 
+            hibernate_set_page_state(vars->page_list, vars->page_list_wired,
                                         atop_64(phys64), atop_32(segLen),
                                         kIOHibernatePageStateFree);
             pageCount -= atop_32(segLen);
@@ -1806,14 +1867,14 @@ hibernate_write_image(void)
 
         pagesDone  = 0;
         lastBlob   = 0;
-    
-        HIBLOG("bitmap_size 0x%x, previewSize 0x%x, writing %d pages @ 0x%llx\n", 
+
+        HIBLOG("bitmap_size 0x%x, previewSize 0x%x, writing %d pages @ 0x%llx\n",
                bitmap_size, header->previewSize,
                pageCount, vars->fileVars->position);
 
         enum
         // pageType
-        { 
+        {
             kWired          = 0x02,
             kEncrypt        = 0x01,
             kWiredEncrypt   = kWired | kEncrypt,
@@ -1835,14 +1896,14 @@ hibernate_write_image(void)
                    vars->fileVars->encryptEnd   = UINT64_MAX;
                    HIBLOG("encryptStart %qx\n", vars->fileVars->encryptStart);
                }
-               bcopy(&cryptvars->aes_iv[0], 
-                       &gIOHibernateCryptWakeContext.aes_iv[0], 
+               bcopy(&cryptvars->aes_iv[0],
+                       &gIOHibernateCryptWakeContext.aes_iv[0],
                        sizeof(cryptvars->aes_iv));
                cryptvars = &gIOHibernateCryptWakeContext;
             }
             for (iterDone = false, ppnum = 0; !iterDone; )
             {
-                count = hibernate_page_list_iterate((kWired & pageType) 
+                count = hibernate_page_list_iterate((kWired & pageType)
                                                             ? vars->page_list_wired : vars->page_list,
                                                         &ppnum);
 //              kprintf("[%d](%x : %x)\n", pageType, ppnum, count);
@@ -1852,7 +1913,7 @@ hibernate_write_image(void)
                 {
                     uint32_t checkIndex;
                     for (checkIndex = 0;
-                            (checkIndex < count) 
+                            (checkIndex < count)
                                 && (((kEncrypt & pageType) == 0) == _pmap_is_noencrypt(ppnum + checkIndex));
                             checkIndex++)
                     {}
@@ -1870,19 +1931,19 @@ hibernate_write_image(void)
                     case kWiredClear:     wiredPagesClear     += count; break;
                     case kUnwiredEncrypt: dirtyPagesEncrypted += count; break;
                 }
-    
+
                 if (iterDone && (kWiredEncrypt == pageType))   {/* not yet end of wired list */}
                 else
                 {
                     pageAndCount[0] = ppnum;
                     pageAndCount[1] = count;
-                    err = IOHibernatePolledFileWrite(vars->fileVars, 
-                                            (const uint8_t *) &pageAndCount, sizeof(pageAndCount), 
+                    err = IOHibernatePolledFileWrite(vars->fileVars,
+                                            (const uint8_t *) &pageAndCount, sizeof(pageAndCount),
                                             cryptvars);
                     if (kIOReturnSuccess != err)
                         break;
                 }
-    
+
                 for (page = ppnum; page < (ppnum + count); page++)
                 {
                     err = IOMemoryDescriptorWriteFromPhysical(vars->srcBuffer, 0, ptoa_64(page), page_size);
@@ -1891,16 +1952,16 @@ hibernate_write_image(void)
                         HIBLOG("IOMemoryDescriptorWriteFromPhysical %d [%ld] %x\n", __LINE__, (long)page, err);
                         break;
                     }
-        
+
                     sum = hibernate_sum_page(src, page);
                     if (kWired & pageType)
                         sum1 += sum;
                     else
                         sum2 += sum;
-       
+
                     clock_get_uptime(&startTime);
                     wkresult = WKdm_compress_new((const WK_word*) src,
-                                                (WK_word*) compressed, 
+                                                (WK_word*) compressed,
                                                 (WK_word*) scratch,
                                                 page_size - 4);
 
@@ -1911,7 +1972,7 @@ hibernate_write_image(void)
                     compBytes += page_size;
                     pageCompressedSize = (-1 == wkresult) ? page_size : wkresult;
 
-                   if (pageCompressedSize == 0) 
+                   if (pageCompressedSize == 0)
                    {
                        pageCompressedSize = 4;
                         data = src;
@@ -1921,27 +1982,27 @@ hibernate_write_image(void)
                        else
                                zvPageCount++;
                    }
-                   else 
+                   else
                    {
                        if (pageCompressedSize != page_size)
                            data = compressed;
                        else
                            data = src;
                    }
-    
+
                     tag = pageCompressedSize | kIOHibernateTagSignature;
                     err = IOHibernatePolledFileWrite(vars->fileVars, (const uint8_t *) &tag, sizeof(tag), cryptvars);
                     if (kIOReturnSuccess != err)
                         break;
-    
+
                     err = IOHibernatePolledFileWrite(vars->fileVars, data, (pageCompressedSize + 3) & ~3, cryptvars);
                     if (kIOReturnSuccess != err)
                         break;
-    
+
                     compressedSize += pageCompressedSize;
                     uncompressedSize += page_size;
                     pagesDone++;
-    
+
                     if (vars->consoleMapping && (0 == (1023 & pagesDone)))
                     {
                         blob = ((pagesDone * kIOHibernateProgressCount) / pageCount);
@@ -2012,12 +2073,12 @@ hibernate_write_image(void)
         }
 
         // Header:
-    
+
         header->imageSize    = vars->fileVars->position;
         header->image1Size   = image1Size;
         header->bitmapSize   = bitmap_size;
         header->pageCount    = pageCount;
-    
+
         header->restore1Sum  = restore1Sum;
         header->image1Sum    = sum1;
         header->image2Sum    = sum2;
@@ -2025,7 +2086,7 @@ hibernate_write_image(void)
 
        header->compression     = (compressedSize << 8) / uncompressedSize;
        gIOHibernateCompression = header->compression;
-    
+
         count = vars->fileVars->fileExtents->getLength();
         if (count > sizeof(header->fileExtentMap))
         {
@@ -2038,20 +2099,20 @@ hibernate_write_image(void)
 
         header->deviceBase      = vars->fileVars->block0;
         header->deviceBlockSize = vars->fileVars->blockSize;
-    
+
         IOPolledFileSeek(vars->fileVars, 0);
         err = IOHibernatePolledFileWrite(vars->fileVars,
-                                    (uint8_t *) header, sizeof(IOHibernateImageHeader), 
+                                    (uint8_t *) header, sizeof(IOHibernateImageHeader),
                                     cryptvars);
         if (kIOReturnSuccess != err)
             break;
         err = IOHibernatePolledFileWrite(vars->fileVars, 0, 0, cryptvars);
     }
     while (false);
-    
+
     clock_get_uptime(&endTime);
 
-    IOService::getPMRootDomain()->pmStatsRecordEvent( 
+    IOService::getPMRootDomain()->pmStatsRecordEvent(
                         kIOPMStatsHibernateImageWrite | kIOPMStatsEventStopFlag, endTime);
 
     SUB_ABSOLUTETIME(&endTime, &allTime);
@@ -2059,31 +2120,31 @@ hibernate_write_image(void)
     HIBLOG("all time: %qd ms, ", nsec / 1000000ULL);
 
     absolutetime_to_nanoseconds(compTime, &nsec);
-    HIBLOG("comp bytes: %qd time: %qd ms %qd Mb/s, ", 
-               compBytes, 
+    HIBLOG("comp bytes: %qd time: %qd ms %qd Mb/s, ",
+               compBytes,
                nsec / 1000000ULL,
                nsec ? (((compBytes * 1000000000ULL) / 1024 / 1024) / nsec) : 0);
 
     absolutetime_to_nanoseconds(vars->fileVars->cryptTime, &nsec);
-    HIBLOG("crypt bytes: %qd time: %qd ms %qd Mb/s, ", 
-               vars->fileVars->cryptBytes, 
-               nsec / 1000000ULL, 
+    HIBLOG("crypt bytes: %qd time: %qd ms %qd Mb/s, ",
+               vars->fileVars->cryptBytes,
+               nsec / 1000000ULL,
                nsec ? (((vars->fileVars->cryptBytes * 1000000000ULL) / 1024 / 1024) / nsec) : 0);
 
-    HIBLOG("\nimage %qd (%lld%%), uncompressed %qd (%d), compressed %qd (%d%%), sum1 %x, sum2 %x\n", 
+    HIBLOG("\nimage %qd (%lld%%), uncompressed %qd (%d), compressed %qd (%d%%), sum1 %x, sum2 %x\n",
                header->imageSize, (header->imageSize * 100) / vars->fileVars->fileSize,
                uncompressedSize, atop_32(uncompressedSize), compressedSize,
                uncompressedSize ? ((int) ((compressedSize * 100ULL) / uncompressedSize)) : 0,
                sum1, sum2);
 
-    HIBLOG("svPageCount %d, zvPageCount %d, wiredPagesEncrypted %d, wiredPagesClear %d, dirtyPagesEncrypted %d\n", 
+    HIBLOG("svPageCount %d, zvPageCount %d, wiredPagesEncrypted %d, wiredPagesClear %d, dirtyPagesEncrypted %d\n",
           svPageCount, zvPageCount, wiredPagesEncrypted, wiredPagesClear, dirtyPagesEncrypted);
 
     if (pollerOpen)
         IOPolledFilePollersClose(vars->fileVars, (kIOReturnSuccess == err) ? kIOPolledBeforeSleepState : kIOPolledBeforeSleepStateAborted );
 
     if (vars->consoleMapping)
-        ProgressUpdate(gIOHibernateGraphicsInfo, 
+        ProgressUpdate(gIOHibernateGraphicsInfo,
                         vars->consoleMapping, 0, kIOHibernateProgressCount);
 
     HIBLOG("hibernate_write_image done(%x)\n", err);
@@ -2123,7 +2184,7 @@ hibernate_write_image(void)
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-extern "C" void 
+extern "C" void
 hibernate_machine_init(void)
 {
     IOReturn     err;
@@ -2155,7 +2216,7 @@ hibernate_machine_init(void)
     }
 
     HIBPRINT("diag %x %x %x %x\n",
-           gIOHibernateCurrentHeader->diag[0], gIOHibernateCurrentHeader->diag[1], 
+           gIOHibernateCurrentHeader->diag[0], gIOHibernateCurrentHeader->diag[1],
            gIOHibernateCurrentHeader->diag[2], gIOHibernateCurrentHeader->diag[3]);
 
 #define t40ms(x)       (tmrCvt((((uint64_t)(x)) << 8), tscFCvtt2n) / 1000000)
@@ -2179,7 +2240,7 @@ hibernate_machine_init(void)
                        gIOHibernateStats->booterStart, gIOHibernateStats->booterDuration,
                        gIOHibernateStats->trampolineDuration);
 
-    HIBLOG("booter start at %d ms smc %d ms, [%d, %d, %d] total %d ms, dsply %d, %d ms, tramp %d ms\n", 
+    HIBLOG("booter start at %d ms smc %d ms, [%d, %d, %d] total %d ms, dsply %d, %d ms, tramp %d ms\n",
           gIOHibernateStats->booterStart,
           gIOHibernateStats->smcStart,
           gIOHibernateStats->booterDuration0,
@@ -2194,7 +2255,7 @@ hibernate_machine_init(void)
            gIOHibernateState, pagesDone, sum, gIOHibernateStats->imageSize, gIOHibernateStats->image1Size,
            gIOHibernateCurrentHeader->conflictCount, gIOHibernateCurrentHeader->nextFree);
 
-    if ((0 != (kIOHibernateModeSleep & gIOHibernateMode)) 
+    if ((0 != (kIOHibernateModeSleep & gIOHibernateMode))
      && (0 != ((kIOHibernateModeDiscardCleanActive | kIOHibernateModeDiscardCleanInactive) & gIOHibernateMode)))
     {
         hibernate_page_list_discard(vars->page_list);
@@ -2206,8 +2267,9 @@ hibernate_machine_init(void)
        panic("handoff overflow");
 
     IOHibernateHandoff * handoff;
-    bool                 done           = false;
-    bool                 foundCryptData = false;
+    bool                 done                   = false;
+    bool                 foundCryptData         = false;
+    bool                 foundVolumeEncryptData = false;
 
     for (handoff = (IOHibernateHandoff *) vars->handoffBuffer->getBytesNoCopy();
         !done;
@@ -2239,18 +2301,27 @@ hibernate_machine_init(void)
                bzero(data, handoff->bytecount);
                break;
 
+           case kIOHibernateHandoffTypeVolumeCryptKey:
+               if (handoff->bytecount == vars->volumeCryptKeySize)
+               {
+                   bcopy(data, &vars->volumeCryptKey[0], vars->volumeCryptKeySize);
+                   foundVolumeEncryptData = true;
+               }
+               else panic("kIOHibernateHandoffTypeVolumeCryptKey(%d)", handoff->bytecount);
+               break;
+
            case kIOHibernateHandoffTypeMemoryMap:
 
                clock_get_uptime(&allTime);
 
-               hibernate_newruntime_map(data, handoff->bytecount, 
+               hibernate_newruntime_map(data, handoff->bytecount,
                                         gIOHibernateCurrentHeader->systemTableOffset);
 
                clock_get_uptime(&endTime);
-           
+
                SUB_ABSOLUTETIME(&endTime, &allTime);
                absolutetime_to_nanoseconds(endTime, &nsec);
-           
+
                HIBLOG("hibernate_newruntime_map time: %qd ms, ", nsec / 1000000ULL);
 
                break;
@@ -2265,30 +2336,33 @@ hibernate_machine_init(void)
            default:
                done = (kIOHibernateHandoffType != (handoff->type & 0xFFFF0000));
                break;
-       }    
+       }
     }
-    if (cryptvars && !foundCryptData)
-       panic("hibernate handoff");
+
+    if (vars->hwEncrypt && !foundVolumeEncryptData)
+       panic("no volumeCryptKey");
+    else if (cryptvars && !foundCryptData)
+       panic("hibernate handoff");
 
     HIBPRINT("video 0x%llx %d %d %d status %x\n",
-           gIOHibernateGraphicsInfo->physicalAddress, gIOHibernateGraphicsInfo->depth, 
-           gIOHibernateGraphicsInfo->width, gIOHibernateGraphicsInfo->height, gIOHibernateGraphicsInfo->gfxStatus); 
+           gIOHibernateGraphicsInfo->physicalAddress, gIOHibernateGraphicsInfo->depth,
+           gIOHibernateGraphicsInfo->width, gIOHibernateGraphicsInfo->height, gIOHibernateGraphicsInfo->gfxStatus);
 
     if (vars->videoMapping && gIOHibernateGraphicsInfo->physicalAddress)
     {
-        vars->videoMapSize = round_page(gIOHibernateGraphicsInfo->height 
+        vars->videoMapSize = round_page(gIOHibernateGraphicsInfo->height
                                         * gIOHibernateGraphicsInfo->rowBytes);
        if (vars->videoMapSize > vars->videoAllocSize) vars->videoMapSize = 0;
        else
        {
-           IOMapPages(kernel_map, 
+           IOMapPages(kernel_map,
                        vars->videoMapping, gIOHibernateGraphicsInfo->physicalAddress,
                        vars->videoMapSize, kIOMapInhibitCache );
        }
     }
 
     if (vars->videoMapSize)
-        ProgressUpdate(gIOHibernateGraphicsInfo, 
+        ProgressUpdate(gIOHibernateGraphicsInfo,
                         (uint8_t *) vars->videoMapping, 0, kIOHibernateProgressCount);
 
     uint8_t * src = (uint8_t *) vars->srcBuffer->getBytesNoCopy();
@@ -2308,6 +2382,14 @@ hibernate_machine_init(void)
     absolutetime_to_nanoseconds(endTime, &nsec);
     HIBLOG("IOPolledFilePollersOpen(%x) %qd ms\n", err, nsec / 1000000ULL);
 
+    if (vars->hwEncrypt)
+    {
+       err = IOPolledFilePollersSetEncryptionKey(vars->fileVars,
+               &vars->volumeCryptKey[0], vars->volumeCryptKeySize);
+       HIBLOG("IOPolledFilePollersSetEncryptionKey(%x)\n", err);
+       if (kIOReturnSuccess != err) panic("IOPolledFilePollersSetEncryptionKey(0x%x)", err);
+    }
+
     IOPolledFileSeek(vars->fileVars, gIOHibernateCurrentHeader->image1Size);
 
     // kick off the read ahead
@@ -2371,14 +2453,14 @@ hibernate_machine_init(void)
                if (compressedSize == 4) {
                    int i;
                    uint32_t *s, *d;
-                       
+
                    s = (uint32_t *)src;
                    d = (uint32_t *)(uintptr_t)compressed;
 
                    for (i = 0; i < (int)(PAGE_SIZE / sizeof(int32_t)); i++)
                        *d++ = *s;
                }
-               else 
+               else
                    WKdm_decompress_new((WK_word*) src, (WK_word*) compressed, (WK_word*) scratch, compressedSize);
                clock_get_uptime(&endTime);
                ADD_ABSOLUTETIME(&compTime, &endTime);
@@ -2408,7 +2490,7 @@ hibernate_machine_init(void)
                if (progressStamp != lastProgressStamp)
                {
                    lastProgressStamp = progressStamp;
-                   HIBPRINT("pages %d (%d%%)\n", pagesDone, 
+                   HIBPRINT("pages %d (%d%%)\n", pagesDone,
                            (100 * pagesDone) / gIOHibernateCurrentHeader->pageCount);
                }
            }
@@ -2429,9 +2511,9 @@ hibernate_machine_init(void)
 
     clock_get_uptime(&endTime);
 
-    IOService::getPMRootDomain()->pmStatsRecordEvent( 
+    IOService::getPMRootDomain()->pmStatsRecordEvent(
                         kIOPMStatsHibernateImageRead | kIOPMStatsEventStartFlag, allTime);
-    IOService::getPMRootDomain()->pmStatsRecordEvent( 
+    IOService::getPMRootDomain()->pmStatsRecordEvent(
                         kIOPMStatsHibernateImageRead | kIOPMStatsEventStopFlag, endTime);
 
     SUB_ABSOLUTETIME(&endTime, &allTime);
@@ -2443,20 +2525,20 @@ hibernate_machine_init(void)
     gIOHibernateStats->kernelImageReadDuration = nsec / 1000000ULL;
     gIOHibernateStats->imagePages              = pagesDone;
 
-    HIBLOG("hibernate_machine_init pagesDone %d sum2 %x, time: %d ms, disk(0x%x) %qd Mb/s, ", 
+    HIBLOG("hibernate_machine_init pagesDone %d sum2 %x, time: %d ms, disk(0x%x) %qd Mb/s, ",
                pagesDone, sum, gIOHibernateStats->kernelImageReadDuration, kDefaultIOSize,
                nsecIO ? ((((gIOHibernateCurrentHeader->imageSize - gIOHibernateCurrentHeader->image1Size) * 1000000000ULL) / 1024 / 1024) / nsecIO) : 0);
 
     absolutetime_to_nanoseconds(compTime, &nsec);
-    HIBLOG("comp bytes: %qd time: %qd ms %qd Mb/s, ", 
-               compBytes, 
+    HIBLOG("comp bytes: %qd time: %qd ms %qd Mb/s, ",
+               compBytes,
                nsec / 1000000ULL,
                nsec ? (((compBytes * 1000000000ULL) / 1024 / 1024) / nsec) : 0);
 
     absolutetime_to_nanoseconds(vars->fileVars->cryptTime, &nsec);
-    HIBLOG("crypt bytes: %qd time: %qd ms %qd Mb/s\n", 
-               vars->fileVars->cryptBytes, 
-               nsec / 1000000ULL, 
+    HIBLOG("crypt bytes: %qd time: %qd ms %qd Mb/s\n",
+               vars->fileVars->cryptBytes,
+               nsec / 1000000ULL,
                nsec ? (((vars->fileVars->cryptBytes * 1000000000ULL) / 1024 / 1024) / nsec) : 0);
 
     KDBG(IOKDBG_CODE(DBG_HIBERNATE, 2), pagesRead, pagesDone);
@@ -2523,6 +2605,3 @@ void IOHibernateSystemRestart(void)
     if (noteProp)               noteProp->release();
     if (sym)                    sym->release();
 }
-
-
-
index 0c800aec59b7861ce7066a37b4cbbf7efb6b3a68..7fd0ec46139e9cdfd37178a6de7f56e5dd93659f 100644 (file)
@@ -53,9 +53,11 @@ struct IOHibernateVars
     uint8_t *                          consoleMapping;
     uint8_t                            haveFastBoot;
     uint8_t                            saveBootAudioVolume;
+    uint8_t                            hwEncrypt;
     uint8_t                            wiredCryptKey[kIOHibernateAESKeySize / 8];
     uint8_t                            cryptKey[kIOHibernateAESKeySize / 8];
-    uint8_t                            volumeCryptKey[kIOHibernateAESKeySize / 8];
+    size_t                             volumeCryptKeySize;
+    uint8_t                            volumeCryptKey[64];
 };
 typedef struct IOHibernateVars IOHibernateVars;
 
index 81f07dcabf6a7a7253743d739e5b576dcb774569..2ee2e146644818fa82cbcfcba5ad0da62c5e9191 100644 (file)
@@ -466,8 +466,6 @@ IOReturn IOSharedInterruptController::initInterruptController(IOInterruptControl
 {
   int      cnt, interruptType;
   IOReturn error;
-
-  reserved = NULL;
   
   if (!super::init())
     return kIOReturnNoResources;
index 85507aa65ae6ea375393b870b3be7b25f2aa3289..fc75dc6cce5b7ef86fcce50cf5d9cee0d902434f 100644 (file)
@@ -38,6 +38,7 @@ __BEGIN_DECLS
 #include <mach/memory_object_types.h>
 #include <device/device_port.h>
 #include <IOKit/IODMACommand.h>
+#include <IOKit/IOKitServer.h>
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -97,16 +98,6 @@ IOMemoryMapTracking(IOTrackingUser * tracking, task_t * task,
 
 extern vm_size_t debug_iomallocpageable_size;
 
-// osfmk/device/iokit_rpc.c
-extern kern_return_t IOMapPages(vm_map_t map, mach_vm_address_t va, mach_vm_address_t pa,
-                                 mach_vm_size_t length, unsigned int mapFlags);
-extern kern_return_t IOUnmapPages(vm_map_t map, mach_vm_address_t va, mach_vm_size_t length);
-
-extern kern_return_t IOProtectCacheMode(vm_map_t map, mach_vm_address_t va,
-                                       mach_vm_size_t length, unsigned int mapFlags);
-
-extern ppnum_t IOGetLastPageNumber(void);
-
 extern ppnum_t gIOLastPage;
 
 extern IOSimpleLock * gIOPageAllocLock;
index ce2963317f0379ec46747694991538a1b3cb9842..9dfb2f322cfd28797a57eab3b0cd63ae168eecec 100644 (file)
@@ -68,10 +68,6 @@ __BEGIN_DECLS
 extern ppnum_t pmap_find_phys(pmap_t pmap, addr64_t va);
 extern void ipc_port_release_send(ipc_port_t port);
 
-// osfmk/device/iokit_rpc.c
-unsigned int IODefaultCacheBits(addr64_t pa);
-unsigned int  IOTranslateCacheBits(struct phys_entry *pp);
-
 __END_DECLS
 
 #define kIOMapperWaitSystem    ((IOMapper *) 1)
@@ -2075,6 +2071,8 @@ IOReturn IOGeneralMemoryDescriptor::dmaCommandOperation(DMACommandOps op, void *
            keepMap = (data->fMapper == gIOSystemMapper);
            keepMap &= ((data->fOffset == 0) && (data->fLength == _length));
 
+           if ((data->fMapper == gIOSystemMapper) && _prepareLock) IOLockLock(_prepareLock);
+
            remap = (!keepMap);
            remap |= (dataP->fDMAMapNumAddressBits < 64)
                  && ((dataP->fMappedBase + _length) > (1ULL << dataP->fDMAMapNumAddressBits));
@@ -2099,6 +2097,8 @@ IOReturn IOGeneralMemoryDescriptor::dmaCommandOperation(DMACommandOps op, void *
                md->dmaMapRecord(data->fMapper, data->fCommand, dataP->fMappedLength);
            }
            data->fMapContig = !dataP->fDiscontig;
+
+           if ((data->fMapper == gIOSystemMapper) && _prepareLock) IOLockUnlock(_prepareLock);
        }
        return (err);                           
     }
@@ -4708,16 +4708,17 @@ void * IOMemoryDescriptor::getVirtualSegment(IOByteCount offset,
 
 bool IOGeneralMemoryDescriptor::serialize(OSSerialize * s) const
 {
-    OSSymbol const *keys[2];
-    OSObject *values[2];
+    OSSymbol const *keys[2] = {0};
+    OSObject *values[2] = {0};
     OSArray * array;
+    vm_size_t vcopy_size;
 
     struct SerData {
        user_addr_t address;
        user_size_t length;
-    } *vcopy;
+    } *vcopy = NULL;
     unsigned int index, nRanges;
-    bool result;
+    bool result = false;
 
     IOOptionBits type = _flags & kIOMemoryTypeMask;
 
@@ -4727,17 +4728,19 @@ bool IOGeneralMemoryDescriptor::serialize(OSSerialize * s) const
     if (!array)  return (false);
 
     nRanges = _rangesCount;
-    vcopy = (SerData *) IOMalloc(sizeof(SerData) * nRanges);
-    if (vcopy == 0) return false;
+    if (os_mul_overflow(sizeof(SerData), nRanges, &vcopy_size)) {
+        result = false;
+        goto bail;
+    }
+    vcopy = (SerData *) IOMalloc(vcopy_size);
+    if (vcopy == 0) {
+        result = false;
+        goto bail;
+    }
 
     keys[0] = OSSymbol::withCString("address");
     keys[1] = OSSymbol::withCString("length");
 
-    result = false;
-    values[0] = values[1] = 0;
-
-    // From this point on we can go to bail.
-
     // Copy the volatile data so we don't have to allocate memory
     // while the lock is held.
     LOCK;
@@ -4797,7 +4800,7 @@ bool IOGeneralMemoryDescriptor::serialize(OSSerialize * s) const
     if (keys[1])
       keys[1]->release();
     if (vcopy)
-        IOFree(vcopy, sizeof(SerData) * nRanges);
+      IOFree(vcopy, vcopy_size);
 
     return result;
 }
index bf7a07032cf6a5a5c381fa9d4d88bf335d2e9e59..94d6b75dd77d0ce7bb88afa83cf6ef4874ee2d64 100644 (file)
@@ -118,7 +118,9 @@ void IODTNVRAM::registerNVRAMController(IONVRAMController *nvram)
     _nvramController->read(0, _nvramImage, kIODTNVRAMImageSize);
     initNVRAMImage();
   } else {
-    syncOFVariables();
+    IOLockLock(_ofLock);
+    (void) syncVariables();
+    IOLockUnlock(_ofLock);
   }
 }
 
@@ -383,14 +385,13 @@ bool IODTNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject)
   bool     result;
   UInt32   propType, propPerm;
   OSString *tmpString;
-  OSObject *propObject = 0;
-  
+  OSObject *propObject = 0, *oldObject;
+
   if (_ofDict == 0) return false;
-  
+
   // Verify permissions.
   propPerm = getOFVariablePerm(aKey);
-  result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege);
-  if (result != kIOReturnSuccess) {
+  if (IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege) != kIOReturnSuccess) {
     if (propPerm != kOFVariablePermUserWrite) return false;
   }
   if (propPerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return 0;
@@ -410,15 +411,15 @@ bool IODTNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject)
   case kOFVariableTypeBoolean :
     propObject = OSDynamicCast(OSBoolean, anObject);
     break;
-    
+
   case kOFVariableTypeNumber :
     propObject = OSDynamicCast(OSNumber, anObject);
     break;
-    
+
   case kOFVariableTypeString :
     propObject = OSDynamicCast(OSString, anObject);
     break;
-    
+
   case kOFVariableTypeData :
     propObject = OSDynamicCast(OSData, anObject);
     if (propObject == 0) {
@@ -430,17 +431,36 @@ bool IODTNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject)
     }
     break;
   }
-  
+
   if (propObject == 0) return false;
 
   IOLockLock(_ofLock);
+
+  oldObject = _ofDict->getObject(aKey);
+  if (oldObject) {
+    oldObject->retain();
+  }
   result = _ofDict->setObject(aKey, propObject);
-  IOLockUnlock(_ofLock);
 
   if (result) {
-    syncOFVariables();
+    if (syncVariables() != kIOReturnSuccess) {
+        if (oldObject) {
+          _ofDict->setObject(aKey, oldObject);
+        }
+        else {
+          _ofDict->removeObject(aKey);
+        }
+        (void) syncVariables();
+        result = false;
+    }
   }
-  
+
+  if (oldObject) {
+    oldObject->release();
+  }
+
+  IOLockUnlock(_ofLock);
+
   return result;
 }
 
@@ -475,11 +495,12 @@ void IODTNVRAM::removeProperty(const OSSymbol *aKey)
   if (result) {
     _ofDict->removeObject(aKey);
   }
-  IOLockUnlock(_ofLock);
 
   if (result) {
-    syncOFVariables();
+    (void) syncVariables();
   }
+
+  IOLockUnlock(_ofLock);
 }
 
 IOReturn IODTNVRAM::setProperties(OSObject *properties)
@@ -757,6 +778,11 @@ IOReturn IODTNVRAM::initOFVariables(void)
 }
 
 IOReturn IODTNVRAM::syncOFVariables(void)
+{
+  return kIOReturnUnsupported;
+}
+
+IOReturn IODTNVRAM::syncVariables(void)
 {
   bool                 ok;
   UInt32               length, maxLength;
@@ -764,29 +790,30 @@ IOReturn IODTNVRAM::syncOFVariables(void)
   const OSSymbol       *tmpSymbol;
   OSObject             *tmpObject;
   OSCollectionIterator *iter;
-  
+
+  IOLockAssert(_ofLock, kIOLockAssertOwned);
+
   if ((_ofImage == 0) || (_ofDict == 0) || _systemPaniced) return kIOReturnNotReady;
-  
+
   buffer = tmpBuffer = IONew(UInt8, _ofPartitionSize);
   if (buffer == 0) return kIOReturnNoMemory;
   bzero(buffer, _ofPartitionSize);
-  
+
   ok = true;
   maxLength = _ofPartitionSize;
 
-  IOLockLock(_ofLock);
   iter = OSCollectionIterator::withCollection(_ofDict);
   if (iter == 0) ok = false;
-  
+
   while (ok) {
     tmpSymbol = OSDynamicCast(OSSymbol, iter->getNextObject());
     if (tmpSymbol == 0) break;
-    
+
     // Don't save 'aapl,panic-info'.
     if (tmpSymbol->isEqualTo(kIODTNVRAMPanicInfoKey)) continue;
-    
+
     tmpObject = _ofDict->getObject(tmpSymbol);
-    
+
     length = maxLength;
     ok = convertObjectToProp(tmpBuffer, &length, tmpSymbol, tmpObject);
     if (ok) {
@@ -795,21 +822,20 @@ IOReturn IODTNVRAM::syncOFVariables(void)
     }
   }
   iter->release();
-  IOLockUnlock(_ofLock);
-  
+
   if (ok) {
     bcopy(buffer, _ofImage, _ofPartitionSize);
   }
-  
+
   IODelete(buffer, UInt8, _ofPartitionSize);
-  
+
   if (!ok) return kIOReturnBadArgument;
-  
+
   if (_nvramController != 0) {
-    _nvramController->write(0, _nvramImage, kIODTNVRAMImageSize);
+    return _nvramController->write(0, _nvramImage, kIODTNVRAMImageSize);
   }
-  
-  return kIOReturnSuccess;
+
+  return kIOReturnNotReady;
 }
 
 struct OFVariable {
@@ -1376,7 +1402,7 @@ IOReturn IODTNVRAM::writeNVRAMPropertyType1(IORegistryEntry *entry,
                                            const OSSymbol *propName,
                                            OSData *value)
 {
-  OSData       *oldData;
+  OSData       *oldData, *escapedData;
   OSData       *data = 0;
   const UInt8  *startPtr;
   const UInt8  *propStart;
@@ -1400,9 +1426,10 @@ IOReturn IODTNVRAM::writeNVRAMPropertyType1(IORegistryEntry *entry,
 
   oldData = OSDynamicCast(OSData, _ofDict->getObject(_registryPropertiesKey));
   if (oldData) {
+
     startPtr = (const UInt8 *) oldData->getBytesNoCopy();
     endPtr = startPtr + oldData->getLength();
-    
+
     propStart = startPtr;
     wherePtr = startPtr;
     while (wherePtr < endPtr) {
@@ -1430,7 +1457,7 @@ IOReturn IODTNVRAM::writeNVRAMPropertyType1(IORegistryEntry *entry,
         nvPath = 0;
         nvName = 0;
       }
-        
+
       startPtr = wherePtr;
     }
   }
@@ -1476,22 +1503,39 @@ IOReturn IODTNVRAM::writeNVRAMPropertyType1(IORegistryEntry *entry,
 
     // append prop name
     ok &= data->appendBytes(propName->getCStringNoCopy(), propName->getLength() + 1);
-  
+
     // append escaped data
-    oldData = escapeDataToData(value);
-    ok &= (oldData != 0);
-    if (ok) ok &= data->appendBytes(oldData);
+    escapedData = escapeDataToData(value);
+    ok &= (escapedData != 0);
+    if (ok) ok &= data->appendBytes(escapedData);
 
   } while (false);
 
+  oldData->retain();
   if (ok) {
     ok = _ofDict->setObject(_registryPropertiesKey, data);
   }
 
-  IOLockUnlock(_ofLock);
   if (data) data->release();
 
-  if (ok) syncOFVariables();
+  if (ok) {
+    if (syncVariables() != kIOReturnSuccess) {
+      if (oldData) {
+        _ofDict->setObject(_registryPropertiesKey, oldData);
+      }
+      else {
+        _ofDict->removeObject(_registryPropertiesKey);
+      }
+      (void) syncVariables();
+      ok = false;
+    }
+  }
+
+  if (oldData) {
+    oldData->release();
+  }
+
+  IOLockUnlock(_ofLock);
 
   return ok ? kIOReturnSuccess : kIOReturnNoMemory;
 }
index bf8ecc94f90b70adb79594ed4cb8c4e7c60f4d60..be3dabe71c867c72472bc260c2afad3f116ec795 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2017 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -640,7 +640,7 @@ halt_log_enter(const char * what, const void * pc, uint64_t time)
 
     if (!gHaltLog) return;
     absolutetime_to_nanoseconds(time, &nano);
-    millis = nano / 1000000ULL;
+    millis = nano / NSEC_PER_MSEC;
     if (millis < 100) return;
 
     IOLockLock(gHaltLogLock);
@@ -659,10 +659,28 @@ halt_log_enter(const char * what, const void * pc, uint64_t time)
 
 extern  uint32_t                           gFSState;
 
-extern "C" void IOSystemShutdownNotification(void)
+extern "C" void IOSystemShutdownNotification(int stage)
 {
     uint64_t startTime;
 
+    if (kIOSystemShutdownNotificationStageRootUnmount == stage)
+    {
+#if !CONFIG_EMBEDDED
+        uint64_t nano, millis;
+        startTime = mach_absolute_time();
+        IOService::getPlatform()->waitQuiet(30 * NSEC_PER_SEC);
+        absolutetime_to_nanoseconds(mach_absolute_time() - startTime, &nano);
+        millis = nano / NSEC_PER_MSEC;
+        if (gHaltTimeMaxLog && (millis >= gHaltTimeMaxLog))
+        {
+            printf("waitQuiet() for unmount %qd ms\n", millis);
+        }
+#endif
+        return;
+    }
+
+    assert(kIOSystemShutdownNotificationStageProcessExit == stage);
+
     IOLockLock(gHaltLogLock);
     if (!gHaltLog)
     {
@@ -888,7 +906,7 @@ static UInt32 computeDeltaTimeMS( const AbsoluteTime * startTime, AbsoluteTime *
         *elapsedTime = endTime;
     }
 
-    return (UInt32)(nano / 1000000ULL);
+    return (UInt32)(nano / NSEC_PER_MSEC);
 }
 
 //******************************************************************************
@@ -3257,6 +3275,40 @@ void IOPMrootDomain::handlePublishSleepWakeUUID( bool shouldPublish )
     }
 }
 
+//******************************************************************************
+// IOPMGetSleepWakeUUIDKey
+//
+// Return the truth value of gSleepWakeUUIDIsSet and optionally copy the key.
+// To get the full key -- a C string -- the buffer must large enough for
+// the end-of-string character.
+// The key is expected to be an UUID string
+//******************************************************************************
+
+extern "C" bool
+IOPMCopySleepWakeUUIDKey(char *buffer, size_t buf_len)
+{
+       if (!gSleepWakeUUIDIsSet) {
+               return (false);
+       }
+
+       if (buffer != NULL) {
+               OSString *string;
+
+               string = (OSString *)
+                   gRootDomain->copyProperty(kIOPMSleepWakeUUIDKey);
+
+               if (string == NULL) {
+                       *buffer = '\0';
+               } else {
+                       strlcpy(buffer, string->getCStringNoCopy(), buf_len);
+
+                       string->release();
+               }
+       }
+
+       return (true);
+}
+
 //******************************************************************************
 // initializeBootSessionUUID
 //
@@ -5644,7 +5696,7 @@ void IOPMrootDomain::overridePowerChangeForUIService(
                 absolutetime_to_nanoseconds(now, &nsec);
                 if (kIOLogPMRootDomain & gIOKitDebug)
                     MSG("Graphics suppressed %u ms\n",
-                        ((int)((nsec) / 1000000ULL)));
+                        ((int)((nsec) / NSEC_PER_MSEC)));
             }
             graphicsSuppressed = true;
         }
@@ -7528,7 +7580,7 @@ void IOPMrootDomain::requestFullWake( FullWakeReason reason )
         absolutetime_to_nanoseconds(now, &nsec);
         MSG("full wake %s (reason %u) %u ms\n",
             promotion ? "promotion" : "request",
-            fullWakeReason, ((int)((nsec) / 1000000ULL)));
+            fullWakeReason, ((int)((nsec) / NSEC_PER_MSEC)));
     }
 }
 
@@ -7685,7 +7737,7 @@ void IOPMrootDomain::pmStatsRecordEvent(
 
             if (stopping) {
                 delta = gPMStats.hibWrite.stop - gPMStats.hibWrite.start;
-                IOLog("PMStats: Hibernate write took %qd ms\n", delta/1000000ULL);
+                IOLog("PMStats: Hibernate write took %qd ms\n", delta/NSEC_PER_MSEC);
             }
             break;
         case kIOPMStatsHibernateImageRead:
@@ -7696,7 +7748,7 @@ void IOPMrootDomain::pmStatsRecordEvent(
 
             if (stopping) {
                 delta = gPMStats.hibRead.stop - gPMStats.hibRead.start;
-                IOLog("PMStats: Hibernate read took %qd ms\n", delta/1000000ULL);
+                IOLog("PMStats: Hibernate read took %qd ms\n", delta/NSEC_PER_MSEC);
 
                 publishPMStats = OSData::withBytes(&gPMStats, sizeof(gPMStats));
                 setProperty(kIOPMSleepStatisticsKey, publishPMStats);
index 59c36062ebd65824669684b6267710c31639d433..7372f799ac903e0553e436b9af7df930aa0b7cf6 100644 (file)
@@ -59,6 +59,7 @@ extern "C" {
 #if !CONFIG_EMBEDDED
 
 boolean_t coprocessor_cross_panic_enabled = TRUE;
+#define APPLE_SECURE_BOOT_VARIABLE_GUID "94b73556-2197-4702-82a8-3e1337dafbfb"
 #endif /* !CONFIG_EMBEDDED */
 
 void printDictionaryKeys (OSDictionary * inDictionary, char * inMsg);
@@ -869,7 +870,10 @@ int PEHaltRestart(unsigned int type)
        if (type == kPEPanicRestartCPU) {
            // Notify any listeners that we're done collecting
            // panic data before we call through to do the restart
-           IOCPURunPlatformPanicActions(kPEPanicEnd);
+#if !CONFIG_EMBEDDED
+           if (coprocessor_cross_panic_enabled)
+#endif
+              IOCPURunPlatformPanicActions(kPEPanicEnd);
 
            // Callout to shutdown the disk driver once we've returned from the
            // kPEPanicEnd callback (and we know all core dumps on this system
@@ -1192,7 +1196,7 @@ void IOPlatformExpert::registerNVRAMController(IONVRAMController * caller)
         entry = IORegistryEntry::fromPath( "/options", gIODTPlane );
         if ( entry )
         {
-            data = OSDynamicCast( OSData, entry->getProperty( "EffectiveProductionStatus" ) );
+            data = OSDynamicCast( OSData, entry->getProperty( APPLE_SECURE_BOOT_VARIABLE_GUID":EffectiveProductionStatus" ) );
             if ( data  && ( data->getLength( ) == sizeof( UInt8 ) ) ) {
                     UInt8 *isProdFused = (UInt8 *) data->getBytesNoCopy( );
                     UInt32 debug_flags = 0;
@@ -1619,7 +1623,6 @@ IOPlatformExpertDevice::initWithArgs(
     if( !ok)
        return( false);
 
-    reserved = NULL;
     workLoop = IOWorkLoop::workLoop();
     if (!workLoop)
         return false;
index 821bbc81bb820ddf4fd84bb3968d27668fe1adee..780d64cd846648eefb15579738f1ee37cfaa06fa 100644 (file)
@@ -44,7 +44,7 @@
 
 OSDefineMetaClassAndAbstractStructors(IOPolledInterface, OSObject);
 
-OSMetaClassDefineReservedUnused(IOPolledInterface, 0);
+OSMetaClassDefineReservedUsed(IOPolledInterface, 0);
 OSMetaClassDefineReservedUnused(IOPolledInterface, 1);
 OSMetaClassDefineReservedUnused(IOPolledInterface, 2);
 OSMetaClassDefineReservedUnused(IOPolledInterface, 3);
@@ -293,6 +293,38 @@ IOPolledFilePollersClose(IOPolledFileIOVars * filevars, uint32_t state)
 
     return (err);
 }
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+IOReturn IOPolledInterface::setEncryptionKey(const uint8_t * key, size_t keySize)
+{
+    return (kIOReturnUnsupported);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+IOReturn
+IOPolledFilePollersSetEncryptionKey(IOPolledFileIOVars * filevars,
+                                   const uint8_t * key, size_t keySize)
+{
+    IOReturn              ret = kIOReturnUnsupported;
+    IOReturn              err;
+    int32_t              idx;
+    IOPolledFilePollers * vars = filevars->pollers;
+    IOPolledInterface   * poller;
+
+    for (idx = 0;
+         (poller = (IOPolledInterface *) vars->pollers->getObject(idx));
+         idx++)
+    {
+        poller = (IOPolledInterface *) vars->pollers->getObject(idx);
+        err = poller->setEncryptionKey(key, keySize);
+       if (kIOReturnSuccess == err) ret = err;
+    }
+
+    return (ret);
+}
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 IOMemoryDescriptor *
@@ -471,7 +503,7 @@ IOCopyMediaForDev(dev_t device)
 
 static IOReturn 
 IOGetVolumeCryptKey(dev_t block_dev,  OSString ** pKeyUUID, 
-                   uint8_t * volumeCryptKey, size_t keySize)
+                   uint8_t * volumeCryptKey, size_t keySize)
 {
     IOReturn         err;
     IOService *      part;
@@ -488,9 +520,15 @@ IOGetVolumeCryptKey(dev_t block_dev,  OSString ** pKeyUUID,
     // Try APFS first
     {
         uuid_t volUuid = {0};
-        size_t sizeOut = 0;
-        err = part->callPlatformFunction(APFSMEDIA_GETHIBERKEY, false, &volUuid, volumeCryptKey, &keySize, &sizeOut);
-        if (err == kIOReturnSuccess)
+        err = part->callPlatformFunction(APFSMEDIA_GETHIBERKEY, false, &volUuid, volumeCryptKey, keySize, keySize);
+       if (kIOReturnBadArgument == err)
+       {
+           // apfs fails on buffer size >32
+           *keySize = 32;
+           err = part->callPlatformFunction(APFSMEDIA_GETHIBERKEY, false, &volUuid, volumeCryptKey, keySize, keySize);
+       }
+        if (err != kIOReturnSuccess) *keySize = 0;
+        else
         {
             // No need to create uuid string if it's not requested
             if (pKeyUUID)
@@ -524,8 +562,8 @@ IOGetVolumeCryptKey(dev_t block_dev,  OSString ** pKeyUUID,
             IOLog("volume key err 0x%x\n", err);
         else
         {
-            if (vek.key.keybytecount < keySize) keySize = vek.key.keybytecount;
-            bcopy(&vek.key.keybytes[0], volumeCryptKey, keySize);
+            if (vek.key.keybytecount < *keySize) *keySize = vek.key.keybytecount;
+            bcopy(&vek.key.keybytes[0], volumeCryptKey, *keySize);
         }
         bzero(&vek, sizeof(vek));
 
@@ -548,7 +586,7 @@ IOPolledFileOpen(const char * filename,
                  void * write_file_addr, size_t write_file_len,
                  IOPolledFileIOVars ** fileVars,
                  OSData ** imagePath,
-                 uint8_t * volumeCryptKey, size_t keySize)
+                 uint8_t * volumeCryptKey, size_t keySize)
 {
     IOReturn             err = kIOReturnSuccess;
     IOPolledFileIOVars * vars;
index 12804d24a13292d5adc89efc65ca6fab54f811ea..393a9c03b1642265954584f7a8067e70413d6aca 100644 (file)
@@ -142,7 +142,8 @@ bool IORangeAllocator::allocElement( UInt32 index )
     if( ((numElements == capacity) && capacityIncrement)
      || (!elements)) {
 
-       newCapacity = capacity + capacityIncrement;
+       if (os_add_overflow(capacity, capacityIncrement, &newCapacity))
+           return( false );
        newElements = IONew( IORangeAllocatorElement, newCapacity );
        if( !newElements)
            return( false );
index 207c8dc29fa316f452a0ca3aed6e07662d89331f..5395c1dc362debae2ca187aa814b80f2f1117eff 100644 (file)
@@ -2278,16 +2278,20 @@ void IOService::scheduleTerminatePhase2( IOOptionBits options )
                terminateWorker( options );
             wait = (0 != (__state[1] & kIOServiceBusyStateMask));
             if( wait) {
-                // wait for the victim to go non-busy
+                /* wait for the victim to go non-busy */
                 if( !haveDeadline) {
                     clock_interval_to_deadline( 15, kSecondScale, &deadline );
                     haveDeadline = true;
                 }
+                /* let others do work while we wait */
+                gIOTerminateThread = 0;
+                IOLockWakeup( gJobsLock, (event_t) &gIOTerminateThread, /* one-thread */ false);
                 waitResult = IOLockSleepDeadline( gJobsLock, &gIOTerminateWork,
                                                   deadline, THREAD_UNINT );
-                if(__improbable(waitResult == THREAD_TIMED_OUT)) {
+                if (__improbable(waitResult == THREAD_TIMED_OUT)) {
                     panic("%s[0x%qx]::terminate(kIOServiceSynchronous) timeout\n", getName(), getRegistryEntryID());
-               }
+                }
+                waitToBecomeTerminateThread();
             }
         } while(gIOTerminateWork || (wait && (waitResult != THREAD_TIMED_OUT)));
 
index ad83881cae1f8d98c97f562e181b20a007c4e2da..d331cb2b0a3af0e86dcd791abe62137a82af9c00 100644 (file)
@@ -40,6 +40,7 @@
 #include <IOKit/IOBSD.h>
 #include <IOKit/IOStatisticsPrivate.h>
 #include <IOKit/IOTimeStamp.h>
+#include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/system.h>
 #include <libkern/OSDebug.h>
 #include <sys/proc.h>
@@ -124,45 +125,13 @@ do { \
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-// definitions we should get from osfmk
-
-//typedef struct ipc_port * ipc_port_t;
-typedef natural_t ipc_kobject_type_t;
-
-#define IKOT_IOKIT_SPARE       27
-#define IKOT_IOKIT_CONNECT     29
-#define IKOT_IOKIT_OBJECT      30
-
 extern "C" {
 
-extern ipc_port_t iokit_alloc_object_port( io_object_t obj,
-                       ipc_kobject_type_t type );
-
-extern kern_return_t iokit_destroy_object_port( ipc_port_t port );
-
-extern mach_port_name_t iokit_make_send_right( task_t task,
-                               io_object_t obj, ipc_kobject_type_t type );
-
-extern kern_return_t iokit_mod_send_right( task_t task, mach_port_name_t name, mach_port_delta_t delta );
-
-extern io_object_t iokit_lookup_connect_ref(io_object_t clientRef, ipc_space_t task);
-
-extern io_object_t iokit_lookup_connect_ref_current_task(io_object_t clientRef);
-
-extern ipc_port_t master_device_port;
-
-extern void iokit_retain_port( ipc_port_t port );
-extern void iokit_release_port( ipc_port_t port );
-extern void iokit_release_port_send( ipc_port_t port );
-
-extern kern_return_t iokit_switch_object_port( ipc_port_t port, io_object_t obj, ipc_kobject_type_t type );
-
 #include <mach/mach_traps.h>
 #include <vm/vm_map.h>
 
 } /* extern "C" */
 
-
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
@@ -202,17 +171,28 @@ static IOLock *           gIOObjectPortLock;
 // not in dictForType() for debugging ease
 static OSDictionary *  gIOObjectPorts;
 static OSDictionary *  gIOConnectPorts;
+static OSDictionary *  gIOIdentifierPorts;
 
 OSDictionary * IOMachPort::dictForType( ipc_kobject_type_t type )
 {
     OSDictionary **            dict;
 
-    if( IKOT_IOKIT_OBJECT == type )
-       dict = &gIOObjectPorts;
-    else if( IKOT_IOKIT_CONNECT == type )
-       dict = &gIOConnectPorts;
-    else
-       return( 0 );
+    switch (type)
+    {
+       case IKOT_IOKIT_OBJECT:
+           dict = &gIOObjectPorts;
+           break;
+       case IKOT_IOKIT_CONNECT:
+           dict = &gIOConnectPorts;
+           break;
+       case IKOT_IOKIT_IDENT:
+           dict = &gIOIdentifierPorts;
+           break;
+       default:
+           panic("dictForType %d", type);
+           dict = NULL;
+           break;
+    }
 
     if( 0 == *dict)
         *dict = OSDictionary::withCapacity( 1 );
@@ -507,10 +487,19 @@ extern "C" {
 // functions called from osfmk/device/iokit_rpc.c
 
 void
-iokit_add_reference( io_object_t obj )
+iokit_add_reference( io_object_t obj, ipc_kobject_type_t type )
 {
-    if( obj)
-       obj->retain();
+    IOUserClient * uc;
+
+    if (!obj) return;
+
+    if ((IKOT_IOKIT_CONNECT == type)
+       && (uc = OSDynamicCast(IOUserClient, obj)))
+    {
+       OSIncrementAtomic(&uc->__ipc);
+    }
+
+    obj->retain();
 }
 
 void
@@ -520,18 +509,6 @@ iokit_remove_reference( io_object_t obj )
        obj->release();
 }
 
-void
-iokit_add_connect_reference( io_object_t obj )
-{
-    IOUserClient * uc;
-
-    if (!obj) return;
-
-    if ((uc = OSDynamicCast(IOUserClient, obj))) OSIncrementAtomic(&uc->__ipc);
-
-    obj->retain();
-}
-
 void
 iokit_remove_connect_reference( io_object_t obj )
 {
@@ -1661,9 +1638,41 @@ IOReturn IOUserClient::exportObjectToClient(task_t task,
     name = IOMachPort::makeSendRightForTask( task, obj, IKOT_IOKIT_OBJECT );
 
     *(mach_port_name_t *)clientObj = name;
+
+    if (obj) obj->release();
+
     return kIOReturnSuccess;
 }
 
+IOReturn IOUserClient::copyPortNameForObjectInTask(task_t task,
+                       OSObject *obj, mach_port_name_t * port_name)
+{
+    mach_port_name_t   name;
+
+    name = IOMachPort::makeSendRightForTask( task, obj, IKOT_IOKIT_IDENT );
+
+    *(mach_port_name_t *) port_name = name;
+
+    return kIOReturnSuccess;
+}
+
+IOReturn IOUserClient::copyObjectForPortNameInTask(task_t task, mach_port_name_t port_name,
+                       OSObject **obj)
+{
+    OSObject * object;
+
+    object = iokit_lookup_object_with_port_name(port_name, IKOT_IOKIT_IDENT, task);
+
+    *obj = object;
+
+    return (object ? kIOReturnSuccess : kIOReturnIPCError);
+}
+
+IOReturn IOUserClient::adjustPortNameReferencesInTask(task_t task, mach_port_name_t port_name, mach_port_delta_t delta)
+{
+    return (iokit_mod_send_right(task, port_name, delta));
+}
+
 IOExternalMethod * IOUserClient::getExternalMethodForIndex( UInt32 /* index */)
 {
     return( 0 );
@@ -3620,6 +3629,7 @@ kern_return_t is_io_connect_map_memory_into_task
            mach_port_name_t name __unused =
                IOMachPort::makeSendRightForTask(
                                     into_task, map, IKOT_IOKIT_OBJECT );
+           map->release();
 
         } else {
             // keep it with the user client
@@ -3730,7 +3740,11 @@ kern_return_t is_io_connect_unmap_memory_from_task
 
            mach_port_name_t name = 0;
            if (from_task != current_task())
+           {
                name = IOMachPort::makeSendRightForTask( from_task, map, IKOT_IOKIT_OBJECT );
+               map->release();
+           }
+
            if (name)
            {
                map->userClientUnmap();
@@ -5237,7 +5251,7 @@ kern_return_t iokit_user_client_trap(struct iokit_user_client_trap_args *args)
     IOUserClient *userClient;
 
     if ((userClient = OSDynamicCast(IOUserClient,
-            iokit_lookup_connect_ref_current_task((OSObject *)(args->userClientRef))))) {
+            iokit_lookup_connect_ref_current_task((mach_port_name_t)(uintptr_t)args->userClientRef)))) {
         IOExternalTrap *trap;
         IOService *target = NULL;
 
@@ -5259,6 +5273,24 @@ kern_return_t iokit_user_client_trap(struct iokit_user_client_trap_args *args)
     return result;
 }
 
+/* Routine io_device_tree_entry_exists_with_name */
+kern_return_t is_io_device_tree_entry_exists_with_name(
+       mach_port_t master_port,
+       io_name_t name,
+       boolean_t *exists )
+{
+       OSCollectionIterator *iter;
+
+       if (master_port != master_device_port)
+               return (kIOReturnNotPrivileged);
+
+       iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, name);
+       *exists = iter && iter->getNextObject();
+       OSSafeReleaseNULL(iter);
+
+       return kIOReturnSuccess;
+}
+
 } /* extern "C" */
 
 IOReturn IOUserClient::externalMethod( uint32_t selector, IOExternalMethodArguments * args,
index 173cad67188d6e0f9f789e1677f8110f7901489d..d1ba499d81f9dc6a9ea4d47322c44f31f9c3703a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2018 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
index 890b89946a6b782048362e9110331c63a0a4dedf..27ef74433357d6663bdb543dd060c6b1160a2471 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -940,6 +940,7 @@ IOBSDMountChange(struct mount * mp, uint32_t op)
 #endif /* IOPOLLED_COREFILE */
 }
 
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 extern "C" boolean_t 
index e358b4ec8f2dc4e8eeaacc8f7e70a05928e7a1e3..702bfacbc30ea742facb12a3ce64fba2e4ac6695 100644 (file)
@@ -456,7 +456,7 @@ struct kcdata_type_definition {
 #define STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP 0x912u /* timestamp used for the delta stackshot */
 
 #define STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT 0x940u   /* task_delta_snapshot_v2 */
-#define STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT 0x941u /* thread_delta_snapshot_v2 */
+#define STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT 0x941u /* thread_delta_snapshot_v* */
 
 #define STACKSHOT_KCTYPE_KERN_STACKLR 0x913u          /* uint32_t */
 #define STACKSHOT_KCTYPE_KERN_STACKLR64 0x914u        /* uint64_t */
@@ -704,6 +704,23 @@ struct thread_delta_snapshot_v2 {
        uint8_t   tds_io_tier;
 } __attribute__ ((packed));
 
+struct thread_delta_snapshot_v3 {
+       uint64_t  tds_thread_id;
+       uint64_t  tds_voucher_identifier;
+       uint64_t  tds_ss_flags;
+       uint64_t  tds_last_made_runnable_time;
+       uint32_t  tds_state;
+       uint32_t  tds_sched_flags;
+       int16_t   tds_base_priority;
+       int16_t   tds_sched_priority;
+       uint8_t   tds_eqos;
+       uint8_t   tds_rqos;
+       uint8_t   tds_rqos_override;
+       uint8_t   tds_io_tier;
+       uint64_t  tds_requested_policy;
+       uint64_t  tds_effective_policy;
+} __attribute__ ((packed));
+
 struct io_stats_snapshot
 {
        /*
@@ -805,13 +822,22 @@ typedef struct stackshot_thread_waitinfo {
 
 /* FIXME some of these types aren't clean (fixed width,  packed, and defined *here*) */
 
+struct crashinfo_proc_uniqidentifierinfo {
+       uint8_t                 p_uuid[16];             /* UUID of the main executable */
+       uint64_t                p_uniqueid;             /* 64 bit unique identifier for process */
+       uint64_t                p_puniqueid;            /* unique identifier for process's parent */
+       uint64_t                p_reserve2;             /* reserved for future use */
+       uint64_t                p_reserve3;             /* reserved for future use */
+       uint64_t                p_reserve4;             /* reserved for future use */
+} __attribute__((packed));
+
 #define TASK_CRASHINFO_BEGIN                KCDATA_BUFFER_BEGIN_CRASHINFO
 #define TASK_CRASHINFO_STRING_DESC          KCDATA_TYPE_STRING_DESC
 #define TASK_CRASHINFO_UINT32_DESC          KCDATA_TYPE_UINT32_DESC
 #define TASK_CRASHINFO_UINT64_DESC          KCDATA_TYPE_UINT64_DESC
 
 #define TASK_CRASHINFO_EXTMODINFO           0x801
-#define TASK_CRASHINFO_BSDINFOWITHUNIQID    0x802 /* struct proc_uniqidentifierinfo */
+#define TASK_CRASHINFO_BSDINFOWITHUNIQID    0x802 /* struct crashinfo_proc_uniqidentifierinfo */
 #define TASK_CRASHINFO_TASKDYLD_INFO        0x803
 #define TASK_CRASHINFO_UUID                 0x804
 #define TASK_CRASHINFO_PID                  0x805
index 73cbeb91896232541bbf814fe1edc5067f958b99..0a36b5aa78b33325c349459ca766ba64658b0140 100644 (file)
@@ -29,7 +29,6 @@
 #include <assert.h>
 #include <stdio.h>
 #include <mach/mach_time.h>
-#include <sys/proc_info.h>
 
 /*!
  * @function kcdata_get_typedescription
@@ -347,6 +346,8 @@ kcdata_get_typedescription(unsigned type_id, uint8_t * buffer, uint32_t buffer_s
                _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos);
                _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_rqos_override);
                _SUBTYPE(KC_ST_UINT8, struct thread_delta_snapshot_v2, tds_io_tier);
+               _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_requested_policy);
+               _SUBTYPE(KC_ST_UINT64, struct thread_delta_snapshot_v3, tds_effective_policy);
 
                setup_type_definition(retval, type_id, i, "thread_delta_snapshot");
 
@@ -468,9 +469,9 @@ kcdata_get_typedescription(unsigned type_id, uint8_t * buffer, uint32_t buffer_s
        /* crashinfo types */
        case TASK_CRASHINFO_BSDINFOWITHUNIQID: {
                i = 0;
-               _SUBTYPE_ARRAY(KC_ST_UINT8, struct proc_uniqidentifierinfo, p_uuid, 16);
-               _SUBTYPE(KC_ST_UINT64, struct proc_uniqidentifierinfo, p_uniqueid);
-               _SUBTYPE(KC_ST_UINT64, struct proc_uniqidentifierinfo, p_puniqueid);
+               _SUBTYPE_ARRAY(KC_ST_UINT8, struct crashinfo_proc_uniqidentifierinfo, p_uuid, 16);
+               _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_uniqueid);
+               _SUBTYPE(KC_ST_UINT64, struct crashinfo_proc_uniqidentifierinfo, p_puniqueid);
                /* Ignore the p_reserve fields */
                setup_type_definition(retval, type_id, i, "proc_uniqidentifierinfo");
                break;
diff --git a/libkdd/kdd.framework/Info.plist b/libkdd/kdd.framework/Info.plist
new file mode 100644 (file)
index 0000000..453e675
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>$(DEVELOPMENT_LANGUAGE)</string>
+       <key>CFBundleExecutable</key>
+       <string>$(EXECUTABLE_NAME)</string>
+       <key>CFBundleIdentifier</key>
+       <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>$(PRODUCT_NAME)</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleVersion</key>
+       <string>$(CURRENT_PROJECT_VERSION)</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright Â© 2017 Apple Inc. All rights reserved.</string>
+       <key>NSPrincipalClass</key>
+       <string></string>
+</dict>
+</plist>
diff --git a/libkdd/kdd.framework/module.modulemap b/libkdd/kdd.framework/module.modulemap
new file mode 100644 (file)
index 0000000..cda3d52
--- /dev/null
@@ -0,0 +1,7 @@
+framework module kdd {
+    header "kcdata.h"
+    module kdd_kdd {
+        requires objc
+        header "kdd.h"
+    }
+}
diff --git a/libkdd/kdd.frameworkTests/Info.plist b/libkdd/kdd.frameworkTests/Info.plist
new file mode 100644 (file)
index 0000000..6c40a6c
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>$(DEVELOPMENT_LANGUAGE)</string>
+       <key>CFBundleExecutable</key>
+       <string>$(EXECUTABLE_NAME)</string>
+       <key>CFBundleIdentifier</key>
+       <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>$(PRODUCT_NAME)</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+</dict>
+</plist>
index c7f528035a5f6eabf72272a7a3690b9583e2b586..8a2a75dd611036e3de50551b2ce54a1b939852f6 100644 (file)
@@ -29,9 +29,8 @@
 #ifndef _KDD_H_
 #define _KDD_H_
 
-#include <kcdata.h>
-
 #import <Foundation/Foundation.h>
+#import <kcdata.h>
 
 /*!
  * @class KCDataType
@@ -123,7 +122,7 @@ NSMutableDictionary * _Nullable parseKCDataArray(kcdata_iter_t iter, NSError * _
  *
  */
 
-NSMutableDictionary * _Nullable parseKCDataContainer(kcdata_iter_t * _Nonnull iter_p, NSError * _Nullable * _Nullable error) NS_RETURNS_RETAINED;
+NSMutableDictionary * _Nullable parseKCDataContainer(kcdata_iter_t * _Nonnull iter, NSError * _Nullable * _Nullable error) NS_RETURNS_RETAINED;
 
 /*!
  * @function parseKCDataBuffer
index e36cc086ceba5d8773c3b8fe8e60f9e02e2e0c79..f9e1e542556944000d33697d0226078f32dd8300 100644 (file)
@@ -15,6 +15,7 @@
                081EDD391C23855700A1C138 /* stackshot-sample-cputime.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 081EDD371C23854500A1C138 /* stackshot-sample-cputime.plist.gz */; };
                08238A3B1BFEB5450053190C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 08F1501D1BFEA7AC00F2C89C /* libz.dylib */; };
                0834719E1BF7D05400D67253 /* kcdata.h in Headers */ = {isa = PBXBuildFile; fileRef = 0834719D1BF7D05400D67253 /* kcdata.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               084085AC1FA3CE3D005BAD16 /* kdd.h in Headers */ = {isa = PBXBuildFile; fileRef = 084085AA1FA3CE32005BAD16 /* kdd.h */; settings = {ATTRIBUTES = (Public, ); }; };
                0843EE921BF6AFC600CD4150 /* stackshot-sample in Resources */ = {isa = PBXBuildFile; fileRef = 0843EE911BF6AFB700CD4150 /* stackshot-sample */; };
                0843EE941BF6BAC100CD4150 /* stackshot-sample.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 0843EE931BF6BAB400CD4150 /* stackshot-sample.plist.gz */; };
                08603F371BF69EDE007D3784 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08603F361BF69EDE007D3784 /* Tests.swift */; };
                0860F87B1BFC3857007E1301 /* stackshot-sample-tailspin-2.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 0860F8791BFC3845007E1301 /* stackshot-sample-tailspin-2.plist.gz */; };
                086395B51BF5655D005ED913 /* kdd_main.m in Sources */ = {isa = PBXBuildFile; fileRef = 086395B41BF5655D005ED913 /* kdd_main.m */; };
                086395B91BF565A2005ED913 /* libkdd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C91C93C71ACB58B700119B60 /* libkdd.a */; };
+               0864FD081FA3C127001B7B0B /* kcdata.h in Headers */ = {isa = PBXBuildFile; fileRef = 0834719D1BF7D05400D67253 /* kcdata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               0864FD0A1FA3C2A9001B7B0B /* kcdtypes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9C5C68B1ACDAFDB00BE0E5E /* kcdtypes.c */; };
+               0864FD0B1FA3C2A9001B7B0B /* kcdata_core.m in Sources */ = {isa = PBXBuildFile; fileRef = C9DE39131ACB5A540020F4A3 /* kcdata_core.m */; };
+               0864FD0D1FA3C2A9001B7B0B /* KCDBasicTypeDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = C91C93E11ACB598700119B60 /* KCDBasicTypeDescription.m */; };
+               0864FD0F1FA3C2A9001B7B0B /* KCDStructTypeDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = C91C93E31ACB598700119B60 /* KCDStructTypeDescription.m */; };
+               0864FD111FA3C2A9001B7B0B /* KCDEmbeddedBufferDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 08A4C94B1C4701B800D5F010 /* KCDEmbeddedBufferDescription.m */; };
+               0864FD131FA3C2A9001B7B0B /* kdd.m in Sources */ = {isa = PBXBuildFile; fileRef = C91C93CC1ACB58B700119B60 /* kdd.m */; };
+               0864FD141FA3C2B9001B7B0B /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 08F1501D1BFEA7AC00F2C89C /* libz.dylib */; };
                088C36E01EF323C300ABB2E0 /* stackshot-sample-thread-policy in Resources */ = {isa = PBXBuildFile; fileRef = 088C36DF1EF323AE00ABB2E0 /* stackshot-sample-thread-policy */; };
                088C36E11EF323C300ABB2E0 /* stackshot-sample-thread-policy.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 088C36DE1EF323AE00ABB2E0 /* stackshot-sample-thread-policy.plist.gz */; };
                08A4C94C1C4701B800D5F010 /* KCDEmbeddedBufferDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 08A4C94B1C4701B800D5F010 /* KCDEmbeddedBufferDescription.m */; };
@@ -46,6 +55,8 @@
                08CF18FF1BF9B7B100D05813 /* stackshot-sample-tailspin in Resources */ = {isa = PBXBuildFile; fileRef = 08CF18FD1BF9B79E00D05813 /* stackshot-sample-tailspin */; };
                08CF19001BF9B7B100D05813 /* stackshot-sample-tailspin.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 08CF18FE1BF9B79E00D05813 /* stackshot-sample-tailspin.plist.gz */; };
                08F1501E1BFEA7AC00F2C89C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 08F1501D1BFEA7AC00F2C89C /* libz.dylib */; };
+               08F2AC0A1FA136EB00271A11 /* stackshot-sample-delta-thread-policy in Resources */ = {isa = PBXBuildFile; fileRef = 08F2AC081FA136EB00271A11 /* stackshot-sample-delta-thread-policy */; };
+               08F2AC0B1FA136EB00271A11 /* stackshot-sample-delta-thread-policy.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 08F2AC091FA136EB00271A11 /* stackshot-sample-delta-thread-policy.plist.gz */; };
                1368F0851C87E06A00940FC6 /* exitreason-codesigning.plist.gz in Resources */ = {isa = PBXBuildFile; fileRef = 1368F0841C87E06300940FC6 /* exitreason-codesigning.plist.gz */; };
                1368F0861C87E06C00940FC6 /* exitreason-codesigning in Resources */ = {isa = PBXBuildFile; fileRef = 1368F0831C87E06300940FC6 /* exitreason-codesigning */; };
                13A79CAA1CF8C5D600FFC181 /* stackshot-with-kcid in Resources */ = {isa = PBXBuildFile; fileRef = 13A79CA81CF8C5D200FFC181 /* stackshot-with-kcid */; };
                081EDD361C23854500A1C138 /* stackshot-sample-cputime */ = {isa = PBXFileReference; lastKnownFileType = file; name = "stackshot-sample-cputime"; path = "tests/stackshot-sample-cputime"; sourceTree = SOURCE_ROOT; };
                081EDD371C23854500A1C138 /* stackshot-sample-cputime.plist.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; name = "stackshot-sample-cputime.plist.gz"; path = "tests/stackshot-sample-cputime.plist.gz"; sourceTree = SOURCE_ROOT; };
                0834719D1BF7D05400D67253 /* kcdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = kcdata.h; path = ../osfmk/kern/kcdata.h; sourceTree = "<group>"; };
+               084085AA1FA3CE32005BAD16 /* kdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kdd.h; sourceTree = BUILT_PRODUCTS_DIR; };
+               084085AE1FA3D156005BAD16 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
                0843EE911BF6AFB700CD4150 /* stackshot-sample */ = {isa = PBXFileReference; lastKnownFileType = text; name = "stackshot-sample"; path = "tests/stackshot-sample"; sourceTree = SOURCE_ROOT; };
                0843EE931BF6BAB400CD4150 /* stackshot-sample.plist.gz */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = archive.gzip; name = "stackshot-sample.plist.gz"; path = "tests/stackshot-sample.plist.gz"; sourceTree = SOURCE_ROOT; };
                08603F341BF69EDE007D3784 /* tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
                0860F8791BFC3845007E1301 /* stackshot-sample-tailspin-2.plist.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; name = "stackshot-sample-tailspin-2.plist.gz"; path = "tests/stackshot-sample-tailspin-2.plist.gz"; sourceTree = SOURCE_ROOT; };
                086395B21BF5655D005ED913 /* kdd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kdd; sourceTree = BUILT_PRODUCTS_DIR; };
                086395B41BF5655D005ED913 /* kdd_main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = kdd_main.m; sourceTree = "<group>"; };
+               0864FCEF1FA3C0B7001B7B0B /* kdd.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = kdd.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               0864FCF21FA3C0B7001B7B0B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+               0864FCFC1FA3C0B7001B7B0B /* kdd_frameworkTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = kdd_frameworkTests.m; sourceTree = "<group>"; };
+               0864FCFE1FA3C0B7001B7B0B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                088C36DE1EF323AE00ABB2E0 /* stackshot-sample-thread-policy.plist.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = "stackshot-sample-thread-policy.plist.gz"; sourceTree = "<group>"; };
                088C36DF1EF323AE00ABB2E0 /* stackshot-sample-thread-policy */ = {isa = PBXFileReference; lastKnownFileType = file; path = "stackshot-sample-thread-policy"; sourceTree = "<group>"; };
                08A4C94A1C47019E00D5F010 /* KCDEmbeddedBufferDescription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KCDEmbeddedBufferDescription.h; sourceTree = "<group>"; };
                08CF18FD1BF9B79E00D05813 /* stackshot-sample-tailspin */ = {isa = PBXFileReference; lastKnownFileType = file; name = "stackshot-sample-tailspin"; path = "tests/stackshot-sample-tailspin"; sourceTree = SOURCE_ROOT; };
                08CF18FE1BF9B79E00D05813 /* stackshot-sample-tailspin.plist.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; name = "stackshot-sample-tailspin.plist.gz"; path = "tests/stackshot-sample-tailspin.plist.gz"; sourceTree = SOURCE_ROOT; };
                08F1501D1BFEA7AC00F2C89C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+               08F2AC081FA136EB00271A11 /* stackshot-sample-delta-thread-policy */ = {isa = PBXFileReference; lastKnownFileType = file; path = "stackshot-sample-delta-thread-policy"; sourceTree = "<group>"; };
+               08F2AC091FA136EB00271A11 /* stackshot-sample-delta-thread-policy.plist.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = "stackshot-sample-delta-thread-policy.plist.gz"; sourceTree = "<group>"; };
                1368F0831C87E06300940FC6 /* exitreason-codesigning */ = {isa = PBXFileReference; lastKnownFileType = file; name = "exitreason-codesigning"; path = "tests/exitreason-codesigning"; sourceTree = SOURCE_ROOT; };
                1368F0841C87E06300940FC6 /* exitreason-codesigning.plist.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; name = "exitreason-codesigning.plist.gz"; path = "tests/exitreason-codesigning.plist.gz"; sourceTree = SOURCE_ROOT; };
                13A79CA81CF8C5D200FFC181 /* stackshot-with-kcid */ = {isa = PBXFileReference; lastKnownFileType = file; name = "stackshot-with-kcid"; path = "tests/stackshot-with-kcid"; sourceTree = SOURCE_ROOT; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               0864FCEB1FA3C0B7001B7B0B /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0864FD141FA3C2B9001B7B0B /* libz.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                C91C93C41ACB58B700119B60 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                08603F351BF69EDE007D3784 /* tests */ = {
                        isa = PBXGroup;
                        children = (
+                               08F2AC081FA136EB00271A11 /* stackshot-sample-delta-thread-policy */,
+                               08F2AC091FA136EB00271A11 /* stackshot-sample-delta-thread-policy.plist.gz */,
                                18C577C51F96DB7100C67EB3 /* stackshot-sample-thread-groups-flags.plist.gz */,
                                18C577C11F96DB5100C67EB3 /* stackshot-sample-thread-groups-flags */,
                                C9DCEF001F01C3790000BD02 /* stackshot-sample-instrs-cycles */,
                        path = tests;
                        sourceTree = "<group>";
                };
+               0864FCF01FA3C0B7001B7B0B /* kdd.framework */ = {
+                       isa = PBXGroup;
+                       children = (
+                               084085AE1FA3D156005BAD16 /* module.modulemap */,
+                               0864FCF21FA3C0B7001B7B0B /* Info.plist */,
+                       );
+                       path = kdd.framework;
+                       sourceTree = "<group>";
+               };
+               0864FCFB1FA3C0B7001B7B0B /* kdd.frameworkTests */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0864FCFC1FA3C0B7001B7B0B /* kdd_frameworkTests.m */,
+                               0864FCFE1FA3C0B7001B7B0B /* Info.plist */,
+                       );
+                       path = kdd.frameworkTests;
+                       sourceTree = "<group>";
+               };
+               0864FD061FA3C0C8001B7B0B /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
                08DE68351BFFB70900BC682F /* libkdd */ = {
                        isa = PBXGroup;
                        children = (
                                08A4C94A1C47019E00D5F010 /* KCDEmbeddedBufferDescription.h */,
                                08A4C94B1C4701B800D5F010 /* KCDEmbeddedBufferDescription.m */,
                                C91C93CA1ACB58B700119B60 /* kdd.h */,
+                               084085AA1FA3CE32005BAD16 /* kdd.h */,
                                C91C93CC1ACB58B700119B60 /* kdd.m */,
                        );
                        name = libkdd;
                                0834719D1BF7D05400D67253 /* kcdata.h */,
                                08B480871BF92DFB00B4AAE0 /* kcdata.py */,
                                08603F351BF69EDE007D3784 /* tests */,
+                               0864FCF01FA3C0B7001B7B0B /* kdd.framework */,
+                               0864FCFB1FA3C0B7001B7B0B /* kdd.frameworkTests */,
                                C91C93C81ACB58B700119B60 /* Products */,
+                               0864FD061FA3C0C8001B7B0B /* Frameworks */,
                        );
                        sourceTree = "<group>";
                };
                                C91C93C71ACB58B700119B60 /* libkdd.a */,
                                086395B21BF5655D005ED913 /* kdd */,
                                08603F341BF69EDE007D3784 /* tests.xctest */,
+                               0864FCEF1FA3C0B7001B7B0B /* kdd.framework */,
                        );
                        name = Products;
                        sourceTree = "<group>";
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
+               0864FCEC1FA3C0B7001B7B0B /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               084085AC1FA3CE3D005BAD16 /* kdd.h in Headers */,
+                               0864FD081FA3C127001B7B0B /* kcdata.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                C91C93C51ACB58B700119B60 /* Headers */ = {
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        productReference = 086395B21BF5655D005ED913 /* kdd */;
                        productType = "com.apple.product-type.tool";
                };
+               0864FCEE1FA3C0B7001B7B0B /* kdd.framework */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 0864FD041FA3C0B7001B7B0B /* Build configuration list for PBXNativeTarget "kdd.framework" */;
+                       buildPhases = (
+                               084085AD1FA3CE5A005BAD16 /* ShellScript */,
+                               0864FCEA1FA3C0B7001B7B0B /* Sources */,
+                               0864FCEB1FA3C0B7001B7B0B /* Frameworks */,
+                               0864FCEC1FA3C0B7001B7B0B /* Headers */,
+                               0864FCED1FA3C0B7001B7B0B /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = kdd.framework;
+                       productName = kdd.framework;
+                       productReference = 0864FCEF1FA3C0B7001B7B0B /* kdd.framework */;
+                       productType = "com.apple.product-type.framework";
+               };
                C91C93C61ACB58B700119B60 /* libkdd */ = {
                        isa = PBXNativeTarget;
                        buildConfigurationList = C91C93DA1ACB58B700119B60 /* Build configuration list for PBXNativeTarget "libkdd" */;
                                        086395B11BF5655D005ED913 = {
                                                CreatedOnToolsVersion = 7.3;
                                        };
+                                       0864FCEE1FA3C0B7001B7B0B = {
+                                               CreatedOnToolsVersion = 9.1;
+                                               ProvisioningStyle = Automatic;
+                                       };
                                        C91C93C61ACB58B700119B60 = {
                                                CreatedOnToolsVersion = 7.0;
                                        };
                                C91C93C61ACB58B700119B60 /* libkdd */,
                                086395B11BF5655D005ED913 /* kdd */,
                                08603F331BF69EDE007D3784 /* tests */,
+                               0864FCEE1FA3C0B7001B7B0B /* kdd.framework */,
                        );
                };
 /* End PBXProject section */
                        isa = PBXResourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               08F2AC0A1FA136EB00271A11 /* stackshot-sample-delta-thread-policy in Resources */,
                                18C577C61F96DB7100C67EB3 /* stackshot-sample-thread-groups-flags.plist.gz in Resources */,
                                18C577C31F96DB5200C67EB3 /* stackshot-sample-thread-groups-flags in Resources */,
                                C9DCEF011F01C3810000BD02 /* stackshot-sample-instrs-cycles in Resources */,
                                13D6C5D01C4DDDB6005E617C /* corpse-twr-sample in Resources */,
                                C9D7B5401D1B41D700F1019D /* xnupost_testconfig-sample in Resources */,
                                081725D51C3F476500371A54 /* stackshot-sample-duration in Resources */,
+                               08F2AC0B1FA136EB00271A11 /* stackshot-sample-delta-thread-policy.plist.gz in Resources */,
                                081725D61C3F476500371A54 /* stackshot-sample-duration.plist.gz in Resources */,
                                081EDD381C23855700A1C138 /* stackshot-sample-cputime in Resources */,
                                081EDD391C23855700A1C138 /* stackshot-sample-cputime.plist.gz in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               0864FCED1FA3C0B7001B7B0B /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXResourcesBuildPhase section */
 
+/* Begin PBXShellScriptBuildPhase section */
+               084085AD1FA3CE5A005BAD16 /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                               "$(SRCROOT)/kdd.h",
+                       );
+                       outputPaths = (
+                               "$(BUILT_PRODUCTS_DIR)/kdd.h",
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "perl -pe 's:kcdata.h:kdd/kcdata.h:' ${SRCROOT}/kdd.h  >${SCRIPT_OUTPUT_FILE_0}";
+               };
+/* End PBXShellScriptBuildPhase section */
+
 /* Begin PBXSourcesBuildPhase section */
                08603F301BF69EDE007D3784 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               0864FCEA1FA3C0B7001B7B0B /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0864FD0A1FA3C2A9001B7B0B /* kcdtypes.c in Sources */,
+                               0864FD0B1FA3C2A9001B7B0B /* kcdata_core.m in Sources */,
+                               0864FD0D1FA3C2A9001B7B0B /* KCDBasicTypeDescription.m in Sources */,
+                               0864FD0F1FA3C2A9001B7B0B /* KCDStructTypeDescription.m in Sources */,
+                               0864FD111FA3C2A9001B7B0B /* KCDEmbeddedBufferDescription.m in Sources */,
+                               0864FD131FA3C2A9001B7B0B /* kdd.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                C91C93C31ACB58B700119B60 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        };
                        name = Release;
                };
+               0864FD001FA3C0B7001B7B0B /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+                               CODE_SIGN_IDENTITY = "-";
+                               CODE_SIGN_STYLE = Automatic;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               CURRENT_PROJECT_VERSION = 1;
+                               DEFINES_MODULE = YES;
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               DYLIB_INSTALL_NAME_BASE = "@rpath";
+                               FRAMEWORK_VERSION = A;
+                               GCC_C_LANGUAGE_STANDARD = gnu11;
+                               INFOPLIST_FILE = kdd.framework/Info.plist;
+                               INSTALLHDRS_SCRIPT_PHASE = YES;
+                               INSTALL_PATH = /AppleInternal/Ariadne/Frameworks/;
+                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
+                               MACOSX_DEPLOYMENT_TARGET = 10.13;
+                               MODULEMAP_FILE = "$(SRCROOT)/kdd.framework/module.modulemap";
+                               PRODUCT_BUNDLE_IDENTIFIER = "test.kdd-framework";
+                               PRODUCT_NAME = kdd;
+                               SDKROOT = macosx.internal;
+                               SKIP_INSTALL = NO;
+                               SUPPORTS_TEXT_BASED_API = YES;
+                               VERSIONING_SYSTEM = "apple-generic";
+                               VERSION_INFO_PREFIX = "";
+                       };
+                       name = Debug;
+               };
+               0864FD011FA3C0B7001B7B0B /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+                               CODE_SIGN_IDENTITY = "-";
+                               CODE_SIGN_STYLE = Automatic;
+                               COMBINE_HIDPI_IMAGES = YES;
+                               CURRENT_PROJECT_VERSION = 1;
+                               DEFINES_MODULE = YES;
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               DYLIB_INSTALL_NAME_BASE = "@rpath";
+                               FRAMEWORK_VERSION = A;
+                               GCC_C_LANGUAGE_STANDARD = gnu11;
+                               INFOPLIST_FILE = kdd.framework/Info.plist;
+                               INSTALLHDRS_SCRIPT_PHASE = YES;
+                               INSTALL_PATH = /AppleInternal/Ariadne/Frameworks/;
+                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
+                               MACOSX_DEPLOYMENT_TARGET = 10.13;
+                               MODULEMAP_FILE = "$(SRCROOT)/kdd.framework/module.modulemap";
+                               PRODUCT_BUNDLE_IDENTIFIER = "test.kdd-framework";
+                               PRODUCT_NAME = kdd;
+                               SDKROOT = macosx.internal;
+                               SKIP_INSTALL = NO;
+                               SUPPORTS_TEXT_BASED_API = YES;
+                               VERSIONING_SYSTEM = "apple-generic";
+                               VERSION_INFO_PREFIX = "";
+                       };
+                       name = Release;
+               };
                C91C93D81ACB58B700119B60 /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               0864FD041FA3C0B7001B7B0B /* Build configuration list for PBXNativeTarget "kdd.framework" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               0864FD001FA3C0B7001B7B0B /* Debug */,
+                               0864FD011FA3C0B7001B7B0B /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                C91C93C21ACB58B700119B60 /* Build configuration list for PBXProject "kdd" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 0886e025190619d47d88021b6c9a41703000f47d..7a8a6ffeed0b98408e63bc5ce0015545b3dea7d9 100644 (file)
@@ -1370,6 +1370,10 @@ class Tests: XCTestCase {
         self.testSampleStackshot("stackshot-sample-thread-policy")
     }
 
+    func testDeltaStackshotWithThreadPolicy() {
+        self.testSampleStackshot("stackshot-sample-delta-thread-policy")
+    }
+
     func testStackshotWithInstrsCycles() {
         self.testSampleStackshot("stackshot-sample-instrs-cycles")
     }
diff --git a/libkdd/tests/stackshot-sample-delta-thread-policy b/libkdd/tests/stackshot-sample-delta-thread-policy
new file mode 100644 (file)
index 0000000..a34c83b
Binary files /dev/null and b/libkdd/tests/stackshot-sample-delta-thread-policy differ
diff --git a/libkdd/tests/stackshot-sample-delta-thread-policy.plist.gz b/libkdd/tests/stackshot-sample-delta-thread-policy.plist.gz
new file mode 100644 (file)
index 0000000..c372cbb
Binary files /dev/null and b/libkdd/tests/stackshot-sample-delta-thread-policy.plist.gz differ
index 3d7c2f6e44ab396d48646f2a90bb09bcffbcf065..71b316c8c13f946ab62332ccc0caf057bfe54b34 100644 (file)
@@ -466,7 +466,7 @@ OSMetaClass::~OSMetaClass()
         if (myKext) {
             sAllClassesDict->removeObject(className);
         } else {
-            sAllClassesDict->removeObject((char *)className);
+            sAllClassesDict->removeObject((const char *)className);
         }
     }
     IOLockUnlock(sAllClassesLock);
index 08cf1654cf7059ca4af71e31488f780c7f332b29..ffaef6a68cb826502dbb7e31bd28cd4bd2c0d4d0 100644 (file)
@@ -411,7 +411,7 @@ OSUnserializeBinary(const char *buffer, size_t bufferSize, OSString **errorStrin
                                sym = OSDynamicCast(OSSymbol, sym);
                                if (!sym && (str = OSDynamicCast(OSString, str)))
                                {
-                                   sym = (OSSymbol *) OSSymbol::withString(str);
+                                   sym = const_cast<OSSymbol *>(OSSymbol::withString(str));
                     ok = (sym != 0);
                     if (!ok) break;
                                }
index 835e5f25e6637212bcca5ef3056109fbbaefd209..346f7ffc16bef98038137b1ca4b4e637299aa83e 100644 (file)
@@ -280,7 +280,7 @@ bool OSString::isEqualTo(const OSData *obj) const
       return false;
 
     unsigned int dataLen = obj->getLength ();;
-    char * dataPtr = (char *) obj->getBytesNoCopy ();
+    const char * dataPtr = (const char *) obj->getBytesNoCopy ();
 
     if (dataLen != length) {
 
index e44bee927c4c96df53e90af981c0de2caa69f310..60f1bb2387f4bbe290b2556866ed1d5d49420613 100644 (file)
@@ -2774,7 +2774,7 @@ buildSymbol(parser_state_t *state, object_t *o)
 {
        OSSymbol *symbol;
 
-       symbol = (OSSymbol *)OSSymbol::withCString(o->string);
+       symbol = const_cast<OSSymbol *>(OSSymbol::withCString(o->string));
        if (o->idref >= 0) rememberObject(state, o->idref, symbol);
 
        free(o->string);
index 23e64137c5a32973d11a2bfc93328cdb942afa4c..5bd2167702f45ef755615ee5288e63777feb2bbd 100644 (file)
@@ -1158,7 +1158,7 @@ buildSymbol(parser_state_t *state, object_t *o)
 {
        OSSymbol *symbol;
 
-       symbol = (OSSymbol *)OSSymbol::withCString(o->string);
+       symbol = const_cast<OSSymbol *>(OSSymbol::withCString(o->string));
        if (o->idref >= 0) rememberObject(state, o->idref, symbol);
 
        free(o->string);
index 5291268bc8994eae8d56aa42ec94055c01791678..c448bb853a3de4fd11c161b513dba72c413c3b46 100644 (file)
@@ -21,7 +21,7 @@ SFLAGS+= -include meta_features.h
 
 # Objects that don't want -Wcast-align warning (8474835)
 OSKextLib.cpo_CXXWARNFLAGS_ADD = -Wno-cast-align
-OSKext.cpo_CXXWARNFLAGS_ADD = -Wno-cast-align
+OSKext.cpo_CXXWARNFLAGS_ADD = -Wno-cast-align -Wno-cast-qual
 OSMetaClass.cpo_CXXWARNFLAGS_ADD = -Wno-cast-align
 OSRuntime.cpo_CXXWARNFLAGS_ADD += -Wno-missing-prototypes
 OSUnserialize.cpo_CXXWARNFLAGS_ADD = -Wno-cast-align -Wno-unreachable-code-break
index 332b48d7d01f71545900bea7c985a51cc462bbc7..115f2d082dc108ed79617c77fab51c0004da14ed 100644 (file)
@@ -45,3 +45,8 @@ cc_rand_generate(void *out, size_t outlen)
 
        return error;
 }
+
+int random_buf(void *buf, size_t buflen)
+{
+       return cc_rand_generate(buf, buflen);
+}
index 786a895b2f895e1f62af01e4eda2b8c12ca40bae..78975d48ba021ff67f914a4b92ce61e6d142948d 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <libkern/crypto/crypto_internal.h>
 #include <libkern/crypto/sha2.h>
+#include <libkern/libkern.h>
 #include <kern/debug.h>
 #include <corecrypto/ccdigest.h>
 
@@ -120,22 +121,17 @@ void SHA512_Final(void *digest, SHA512_CTX *ctx)
 
 #else
 
-/* As these are part of the KPI, we need to stub them out for any kernle cofiguration that does not support SHA2. */
-
-void SHA384_Init(__unused SHA384_CTX *ctx)
-{
-       panic("SHA384_Init");
-}
-
-void SHA384_Update(__unused SHA384_CTX *ctx, __unused const void *data, __unused size_t len)
-{
-       panic("SHA384_Update");
-}
-
-void SHA384_Final(__unused void *digest, __unused SHA384_CTX *ctx)
-{
-       panic("SHA384_Final");
-}
+/* As these are part of the KPI, we need to stub them out for any kernel configuration that does not support SHA2. */
+
+void UNSUPPORTED_API(SHA256_Init,   SHA256_CTX *ctx);
+void UNSUPPORTED_API(SHA384_Init,   SHA384_CTX *ctx);
+void UNSUPPORTED_API(SHA512_Init,   SHA512_CTX *ctx);
+void UNSUPPORTED_API(SHA256_Update, SHA256_CTX *ctx, const void *data, size_t len);
+void UNSUPPORTED_API(SHA384_Update, SHA384_CTX *ctx, const void *data, size_t len);
+void UNSUPPORTED_API(SHA512_Update, SHA512_CTX *ctx, const void *data, size_t len);
+void UNSUPPORTED_API(SHA256_Final,  void *digest, SHA256_CTX *ctx);
+void UNSUPPORTED_API(SHA384_Final,  void *digest, SHA384_CTX *ctx);
+void UNSUPPORTED_API(SHA512_Final,  void *digest, SHA512_CTX *ctx);
 
 #endif
 
index 4f08156f7561432b6acbfb2d2a90ec4a1add1bfa..51d399a82fedfe672fbeaf4df9caa4aadd7a4fdb 100644 (file)
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
-
+#include <libkern/libkern.h>
 #include <libkern/crypto/register_crypto.h>
 #include <libkern/crypto/crypto_internal.h>
+#include <libkern/section_keywords.h>
 
-crypto_functions_t g_crypto_funcs = NULL;
+SECURITY_READ_ONLY_LATE(crypto_functions_t) g_crypto_funcs = NULL;
 
 int register_crypto_functions(const crypto_functions_t funcs)
 {
index 581c07b540dc357ee3a9bfc55b38f1266f3179e0..2930a5fc7c70fd7c2d5e5c703b84917b7d2ed69f 100644 (file)
@@ -86,7 +86,6 @@ void OSKextVLog(
 
 #ifdef XNU_KERNEL_PRIVATE
 void OSKextRemoveKextBootstrap(void);
-void IOSystemShutdownNotification(void);
 
 kern_return_t OSRuntimeInitializeCPP(
     kmod_info_t * kmodInfo,
@@ -183,7 +182,6 @@ class OSKext : public OSObject
         va_list          srcArgList);
 
     friend void OSKextRemoveKextBootstrap(void);
-    friend void IOSystemShutdownNotification(void);
     friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t);
 
     friend kern_return_t kext_request(
index 322e5238a2bdaffb6c8e1d650e7d7822abddd5c9..6098d6b790f097f215278c60061c3195a11330d9 100644 (file)
@@ -114,6 +114,12 @@ class OSCollection;
 #define APPLE_KEXT_COMPATIBILITY_OVERRIDE
 #endif
 
+#define APPLE_KEXT_WSHADOW_PUSH _Pragma("clang diagnostic push"); \
+       _Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"") \
+       _Pragma("clang diagnostic ignored \"-Wshadow-field\"")
+
+#define APPLE_KEXT_WSHADOW_POP _Pragma("clang diagnostic pop")
+
 
 /*!
  * @class OSMetaClassBase
@@ -1677,7 +1683,7 @@ public:
         virtual const OSMetaClass * getMetaClass() const APPLE_KEXT_OVERRIDE; \
     protected:                                                  \
     className (const OSMetaClass *);                            \
-    virtual ~ className ()
+    virtual ~ className () APPLE_KEXT_OVERRIDE
 
 
    /*!
index 0fdcb6258f09be3d81aee66f77afde2bc1cc2dab..f5544e8cf6517b969e2c86bd74c410f62660bbac 100644 (file)
@@ -6,9 +6,9 @@ export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
 include $(MakeInc_cmd)
 include $(MakeInc_def)
 
-DATAFILES = md5.h sha1.h
+DATAFILES = md5.h rand.h sha1.h
 
-PRIVATE_DATAFILES = register_crypto.h sha2.h des.h aes.h aesxts.h rand.h rsa.h chacha20poly1305.h
+PRIVATE_DATAFILES = register_crypto.h sha2.h des.h aes.h aesxts.h rsa.h chacha20poly1305.h
 
 INSTALL_KF_MI_LIST = ${DATAFILES}
 
index 08778f4cd59efd98cdea4f3b41ef58ce02bdaad6..8d99cf7b99522b76737622caabf3d558674491f4 100644 (file)
 #ifndef _RAND_H
 #define _RAND_H
 
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
+#include <sys/types.h>
+
+__BEGIN_DECLS
 
+#if XNU_KERNEL_PRIVATE
 int cc_rand_generate(void *out, size_t outlen);
+#endif  /* XNU_KERNEL_PRIVATE */
 
-#if defined(__cplusplus)
-}
-#endif
+int random_buf(void *buf, size_t buflen);
+
+__END_DECLS
 
 #endif
index 1eb4f384f35641b04d1ffe95b71629297e935d6b..5aa4cdea60eb52d99769e97436125618af14b66c 100644 (file)
@@ -70,10 +70,6 @@ subs_entry_t kext_identifier_substring_subs[] = {
     { "Controller", 'C' },
     { "Bluetooth",  'B' },
     { "Intel",      'I' },
-    
-    // CHUD kexts, typically not on user installs
-    { "Profile",    'P' },
-    { "Action",     'a' },   // maybe K if we want to stick to all-caps
 
     { (char *)0,    '\0' }
 };
index 80a7508f3148533fceb978e0aec370f0fbbfe7d9..a73df0946000809541121cc8fd58740d2cd30ca9 100644 (file)
@@ -384,7 +384,7 @@ KLDBootstrap::readPrelinkedExtensions(
         panic("kernelcacheUUID length is %d, expected %lu", kernelcacheUUID->getLength(),
             sizeof(kernelcache_uuid));
     } else {
-        memcpy((void *)&kernelcache_uuid, (void *)kernelcacheUUID->getBytesNoCopy(), kernelcacheUUID->getLength());
+        memcpy((void *)&kernelcache_uuid, (const void *)kernelcacheUUID->getBytesNoCopy(), kernelcacheUUID->getLength());
     }
 #endif /* CONFIG_EMBEDDED */
 
@@ -481,8 +481,8 @@ KLDBootstrap::readPrelinkedExtensions(
            int badSlideAddr = 0;
            int badSlideTarget = 0;
 
-        kaslrPackedOffsets * myOffsets = NULL;
-           myOffsets = (kaslrPackedOffsets *) kaslrOffsets->getBytesNoCopy();
+        const kaslrPackedOffsets * myOffsets = NULL;
+           myOffsets = (const kaslrPackedOffsets *) kaslrOffsets->getBytesNoCopy();
 
            for (uint32_t j = 0; j < myOffsets->count; j++) {
 
index 255664d9cb749bec036867fdfaf5822deefba793..39958a1a520a6a1ee81fd4136eae3421524dbece 100644 (file)
@@ -182,6 +182,12 @@ proc_piddynkqueueinfo(int pid, int flavor, kqueue_id_t kq_id, void *buffer, int
        return ret;
 }
 
+int
+proc_udata_info(int pid, int flavor, void *buffer, int buffersize)
+{
+       return (__proc_info(PROC_INFO_CALL_UDATA_INFO, pid, flavor, 0, buffer, buffersize));
+}
+
 int
 proc_name(int pid, void * buffer, uint32_t buffersize)
 {
@@ -218,7 +224,7 @@ proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersiz
                return(0);
        }
        
-       retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, &reginfo, sizeof(struct proc_regionwithpathinfo));
+       retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO2, (uint64_t)address, &reginfo, sizeof(struct proc_regionwithpathinfo));
        if (retval != -1) {
                return ((int)(strlcpy(buffer, reginfo.prp_vip.vip_path, MAXPATHLEN)));
        }
index ccf413fc3b913b62953f0c9eab4152608405ad28..61b69d9b630b309d7883dd7252c5e0f4eec8af28 100644 (file)
@@ -145,6 +145,8 @@ int proc_piddynkqueueinfo(int pid, int flavor, kqueue_id_t kq_id, void *buffer,
                int buffersize);
 #endif /* PRIVATE */
 
+int proc_udata_info(int pid, int flavor, void *buffer, int buffersize);
+
 __END_DECLS
 
 #endif /*_LIBPROC_H_ */
index 96ca9ef8363cdddb845c36bf23e7dab273842cd8..32b43da0635be3caed5006706a5fdeb51d496b19 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <sys/errno.h>
 #include <stdlib.h>
+#include <strings.h>
 
 struct work_interval {
        uint64_t thread_id;
@@ -113,6 +114,7 @@ work_interval_notify_simple(work_interval_t interval_handle, uint64_t start,
                                    deadline, next_start, 0);
 }
 
+
 int
 work_interval_destroy(work_interval_t interval_handle)
 {
index 8c49bd74b01b3c9d58a4c6b1771c4dfe1d6501c9..dcba4ab78590dc2e3643e6bad715e64303dcd042 100644 (file)
@@ -103,18 +103,8 @@ endif
 # Shared C/C++ warning flags
 WARNFLAGS_STD := \
        -Weverything \
-       -Wextra \
+       -Wno-pedantic \
        $(WERROR) \
-       -Wpointer-arith \
-       -Wreturn-type \
-       -Wcast-qual \
-       -Wwrite-strings \
-       -Wswitch \
-       -Wcast-align \
-       -Wchar-subscripts \
-       -Wredundant-decls \
-       -Wextra-tokens \
-       -Wunreachable-code \
        -Wno-assign-enum \
        -Wno-bad-function-cast \
        -Wno-c++98-compat \
@@ -141,7 +131,6 @@ WARNFLAGS_STD := \
        -Wno-packed \
        -Wno-padded \
        -Wno-partial-availability \
-       -Wno-pedantic \
        -Wno-shift-sign-overflow \
        -Wno-switch-enum \
        -Wno-undef \
@@ -151,13 +140,13 @@ WARNFLAGS_STD := \
        -Wno-vla \
        -Wno-zero-length-array
 
+WARNFLAGS_STD := $(WARNFLAGS_STD) \
+       -Wno-unknown-warning-option \
+       -Wno-error=shadow-field \
+       -Wno-error=cast-qual
+
 CWARNFLAGS_STD = \
-       $(WARNFLAGS_STD) \
-       -Wstrict-prototypes \
-       -Wmissing-prototypes \
-       -Wshadow \
-       -Winline \
-       -Wnested-externs
+       $(WARNFLAGS_STD)
 
 # Can be overridden in Makefile.template or Makefile.$arch
 export CWARNFLAGS ?= $(CWARNFLAGS_STD)
@@ -171,10 +160,8 @@ CXXWARNFLAGS_STD = \
        -Wno-c++98-compat-pedantic \
        -Wno-exit-time-destructors \
        -Wno-global-constructors \
-       -Wno-old-style-cast
-
-# overloaded-virtual warnings are non-fatal (9000888)
-CXXWARNFLAGS_STD += -Wno-error=overloaded-virtual
+       -Wno-old-style-cast \
+       -Wno-zero-as-null-pointer-constant
 
 # Can be overridden in Makefile.template or Makefile.$arch
 export CXXWARNFLAGS ?= $(CXXWARNFLAGS_STD)
@@ -519,7 +506,7 @@ SUPPORTS_CTFCONVERT = 0
 ifeq ($(USE_LTO),1)
 CFLAGS_GEN     += -flto
 CXXFLAGS_GEN   += -flto
-LDFLAGS_KERNEL_GEN     += -Wl,-mllvm,-inline-threshold=125 -Wl,-object_path_lto,$(TARGET)/lto.o # -Wl,-mllvm -Wl,-disable-fp-elim
+LDFLAGS_KERNEL_GEN     += -Wl,-mllvm,-inline-threshold=100 -Wl,-object_path_lto,$(TARGET)/lto.o
 LDFLAGS_NOSTRIP_FLAG = -rdynamic
 CFLAGS_NOLTO_FLAG = -fno-lto
 NEEDS_CTF_MACHOS       = 1
index c552c108a3d44a9a95268daae1e57c04c3f435d4..76fd8500a04043913b8a1a1ed10387608c33d43e 100644 (file)
@@ -545,7 +545,6 @@ CLEAN_RM_DIRS= $(OBJROOT) $(SYMROOT) $(DSTROOT) \
 CLEAN_ACTION_DIRS= $(SRCROOT)/tools/tests/MPMMTest \
                $(SRCROOT)/tools/tests/TLBcoherency \
                $(SRCROOT)/tools/tests/kqueue_tests \
-               $(SRCROOT)/tools/tests/libMicro \
                $(SRCROOT)/tools/tests/mktimer \
                $(SRCROOT)/tools/tests/zero-to-n \
                $(SRCROOT)/tools/tests/personas
index ac41435d41e8ee897ab21ad2cad82b7d07dbeb31..2b9b0a2614c70247f673dca40cbb7fe39293b392 100644 (file)
@@ -54,8 +54,6 @@
 #include <sys/kdebug.h>
 #include <arm/machine_routines.h>
 #include <libkern/OSAtomic.h>
-#include <chud/chud_xnu.h>
-#include <chud/chud_xnu_private.h>
 
 #if KPERF
 void kperf_signal_handler(unsigned int cpu_number);
@@ -406,10 +404,6 @@ cpu_signal_handler_internal(boolean_t disable_signal)
                        (void)hw_atomic_and(&cpu_data_ptr->cpu_signal, ~SIGPdec);
                        rtclock_intr(FALSE);
                }
-               if (cpu_signal & SIGPchud) {
-                       (void)hw_atomic_and(&cpu_data_ptr->cpu_signal, ~SIGPchud);
-                       chudxnu_cpu_signal_handler();
-               }
 #if KPERF
                if (cpu_signal & SIGPkptimer) {
                        (void)hw_atomic_and(&cpu_data_ptr->cpu_signal, ~SIGPkptimer);
index ecef9f9390109391fb829fd136d32b8b3a20d168..e660c1e36ee704e170c6956bc68217d203a02794 100644 (file)
@@ -76,6 +76,7 @@ extern        reset_handler_data_t    ResetHandlerData;
 #define        CPUWINDOWS_BASE_MASK            0xFFFFFFFFFFF00000UL
 #define        CPUWINDOWS_BASE                 (VM_MAX_KERNEL_ADDRESS & CPUWINDOWS_BASE_MASK)
 #endif
+#define CPUWINDOWS_TOP                 (CPUWINDOWS_BASE + (MAX_CPUS * CPUWINDOWS_MAX * PAGE_SIZE))
 
 typedef struct cpu_data_entry {
        void                                    *cpu_data_paddr;             /* Cpu data physical address */
@@ -182,7 +183,6 @@ typedef struct cpu_data
        void                                    *cpu_tbd_hardware_val;
 
        void                                    *cpu_console_buf;
-       void                                    *cpu_chud;
 
        void                                    *cpu_idle_notify;
        uint64_t                                cpu_idle_latency;
index 227863b4c84159a18df34cb7dff28e9684d807b1..c7c846d75c0366cf10d2698f2eb4aebecdf39b82 100644 (file)
@@ -57,7 +57,7 @@ extern void                   cpu_signal_cancel(
 
 #define SIGPnop                        0x00000000U             /* Send IPI with no service */
 #define SIGPdec                        0x00000001U             /* Request decremeter service */
-#define        SIGPchud                0x00000002U             /* CHUD CPU Signal request types */
+/* 0x2U unused */
 #define SIGPxcall              0x00000004U             /* Call a function on a processor */
 #define SIGPast                        0x00000008U             /* Request AST check */
 #define SIGPdebug              0x00000010U             /* Request Debug call */
@@ -67,12 +67,6 @@ extern void                  cpu_signal_cancel(
 
 #define SIGPdisabled           0x80000000U             /* Signal disabled */
 
-extern void *                                  chudxnu_cpu_alloc(
-                                                                               boolean_t boot_processor);
-
-extern void                                            chudxnu_cpu_free(
-                                                                               void *per_proc_chud);
-
 extern unsigned int real_ncpus;
 
 
index 5af8c2a7995d9b8a0b6974703c9a24c3f9e07903..233166b555854a943493afa0e4283585e2bd36bd 100644 (file)
@@ -244,22 +244,99 @@ LEXT(fleh_reset)
        .align 2
        .globl EXT(fleh_undef)
 
-LEXT(fleh_undef)       
-       mrs             sp, spsr                                                        // Check the previous mode
+/*
+ *     Ensures the stack is safely aligned, usually in preparation for an external branch
+ *     arg0: temp register for storing the stack offset
+ *     arg1: temp register for storing the previous stack pointer
+ */
+.macro ALIGN_STACK
+/*
+ * For armv7k ABI, the stack needs to be 16-byte aligned
+ */
+#if __BIGGEST_ALIGNMENT__ > 4
+       and             $0, sp, #0x0F                                           // sp mod 16-bytes
+       cmp             $0, #4                                                  // need space for the sp on the stack
+       addlt           $0, $0, #0x10                                           // make room if needed, but keep stack aligned
+       mov             $1, sp                                                  // get current sp
+       sub             sp, sp, $0                                              // align stack
+       str             $1, [sp]                                                // store previous sp on stack
+#endif
+.endmacro
+
+/*
+ *     Restores the stack pointer to its previous value following an ALIGN_STACK call
+ */
+.macro UNALIGN_STACK
+#if __BIGGEST_ALIGNMENT__ > 4
+       ldr             sp, [sp]
+#endif
+.endmacro
+
+/*
+ *     Checks that cpu is currently in the expected mode, panics if not.
+ *     arg0: the expected mode, should be one of the PSR_*_MODE defines
+ */
+.macro VERIFY_EXCEPTION_MODE
+       mrs             sp, cpsr                                                        // Read cpsr
+       and             sp, sp, #PSR_MODE_MASK                                  // Extract current mode
+       cmp             sp, $0                                                  // Check specified mode
+       movne           r0, sp
+       bne             EXT(ExceptionVectorPanic)
+.endmacro
+
+/*
+ *     Checks previous processor mode.  If usermode, will execute the code
+ *     following the macro to handle the userspace exception.  Otherwise,
+ *     will branch to a ELSE_IF_KERNELMODE_EXCEPTION call with the same
+ *     argument.
+ *     arg0: arbitrary string indicating the exception class, e.g. 'dataabt'
+ */ 
+.macro IF_USERMODE_EXCEPTION
+       mrs             sp, spsr
+       and             sp, sp, #PSR_MODE_MASK                                          // Is it from user?
+       cmp             sp, #PSR_USER_MODE
+       beq             $0_from_user
+       cmp             sp, #PSR_IRQ_MODE
+       beq             $0_from_irq
+       cmp             sp, #PSR_FIQ_MODE
+       beq             $0_from_fiq
+       bne             $0_from_svc
+$0_from_user:
+.endmacro
+
+/*
+ *     Handles an exception taken from kernelmode (IRQ/FIQ/SVC/etc).
+ *     Places the processor into the correct mode and executes the
+ *     code following the macro to handle the kernel exception.
+ *     Intended to be paired with a prior call to IF_USERMODE_EXCEPTION.
+ *     arg0: arbitrary string indicating the exception class, e.g. 'dataabt'
+ */
+.macro ELSE_IF_KERNELMODE_EXCEPTION
+$0_from_irq:
+       cpsid           i, #PSR_IRQ_MODE
+       b               $0_from_kernel
+$0_from_fiq:
+       cpsid           i, #PSR_FIQ_MODE
+       b               $0_from_kernel
+$0_from_svc:
+       cpsid           i, #PSR_SVC_MODE
+$0_from_kernel:
+.endmacro
+
+LEXT(fleh_undef)
+VERIFY_EXCEPTION_MODE PSR_UND_MODE
+       mrs             sp, spsr                                                        // For check the previous mode
        tst             sp, #PSR_TF                                                     // Is it Thumb?
        subeq           lr, lr, #4
        subne           lr, lr, #2
-       tst             sp, #0x0f                                                       // Is it from user?
-       bne             undef_from_kernel
-
-undef_from_user:       
+IF_USERMODE_EXCEPTION undef
        mrc             p15, 0, sp, c13, c0, 4                          // Read TPIDRPRW
        add             sp, sp, ACT_PCBDATA                             // Get current thread PCB pointer
 
        stmia   sp, {r0-r12, sp, lr}^                           // Save user context on PCB
        mov             r7, #0                                                          // Zero the frame pointer
        nop
-               
+
        mov             r0, sp                                                          // Store arm_saved_state pointer 
                                                                                                //  for argument
 
@@ -268,7 +345,6 @@ undef_from_user:
        mrs             r4, spsr
        str             r4, [sp, SS_CPSR]                                       // Save user mode cpsr
 
-       mrs             r4, cpsr                                                        // Read cpsr
        cpsid i, #PSR_SVC_MODE
        mrs             r3, cpsr                                                        // Read cpsr
        msr             spsr_cxsf, r3                       // Set spsr(svc mode cpsr)
@@ -281,9 +357,6 @@ undef_from_user:
        mcr             p15, 0, r3, c13, c0, 1                          // Set CONTEXTIDR
        isb
 #endif
-       and             r0, r4, #PSR_MODE_MASK                          // Extract current mode
-       cmp             r0, #PSR_UND_MODE                                       // Check undef mode
-       bne             EXT(ExceptionVectorPanic)
 
        mvn             r0, #0
        str             r0, [r9, TH_IOTIER_OVERRIDE]                    // Reset IO tier override to -1 before handling abort from userspace
@@ -309,36 +382,11 @@ undef_from_user:
                                                                                                //   sleh will enable interrupt
        b               load_and_go_user
 
-undef_from_kernel:     
-       mrs             sp, cpsr                                                        // Read cpsr
-       and             sp, sp, #PSR_MODE_MASK                          // Extract current mode
-       cmp             sp, #PSR_UND_MODE                                       // Check undef mode
-       movne   r0, sp
-       bne             EXT(ExceptionVectorPanic)
-       mrs             sp, spsr                                                        // Check the previous mode
-
+ELSE_IF_KERNELMODE_EXCEPTION undef
        /*
         * We have a kernel stack already, and I will use it to save contexts
         * IRQ is disabled
         */
-
-#if CONFIG_DTRACE
-       /*
-        * See if we came here from IRQ or SVC mode, and go back to that mode
-        */
-
-       and             sp, sp, #PSR_MODE_MASK
-       cmp             sp, #PSR_IRQ_MODE
-       bne             undef_from_kernel_svc
-
-       cpsid i, #PSR_IRQ_MODE
-       b               handle_undef
-#endif
-
-undef_from_kernel_svc:
-       cpsid i, #PSR_SVC_MODE
-
-handle_undef:
 #if CONFIG_DTRACE
        // We need a frame for backtracing. The LR here is the LR of supervisor mode, not the location where the exception
        // took place. We'll store that later after we switch to undef mode and pull out the LR from there.
@@ -356,31 +404,13 @@ handle_undef:
 #if CONFIG_DTRACE
        add             r7, sp, EXC_CTX_SIZE                                            // Save frame pointer
 #endif
-       
-       mov             ip, sp                                                          // Stack transfer
-
-       cpsid   i, #PSR_UND_MODE
-
-       str             lr, [ip, SS_PC]                                         // Save complete
-       mrs             r4, spsr
-       str             r4, [ip, SS_CPSR]       
-
-#if CONFIG_DTRACE
-       /*
-        * Go back to previous mode for mode specific regs
-        */
-       and             r4, r4, #PSR_MODE_MASK
-       cmp             r4, #PSR_IRQ_MODE
-       bne             handle_undef_from_svc
-
-       cpsid   i, #PSR_IRQ_MODE
-       b               handle_undef2
-#endif
 
-handle_undef_from_svc:
-       cpsid   i, #PSR_SVC_MODE
+       mrs             r4, lr_und
+       str             r4, [sp, SS_PC]                                         // Save complete
+       mrs             r4, spsr_und
+       str             r4, [sp, SS_CPSR]       
 
-handle_undef2:
+       mov             ip, sp
 
 /*
    sp - stack pointer
@@ -431,23 +461,9 @@ handle_undef2:
 #endif
        mov             r0, sp                                                          // Argument
 
-/*
- * For armv7k ABI, the stack needs to be 16-byte aligned
- */
-#if __BIGGEST_ALIGNMENT__ > 4
-       and     r1, sp, #0x0F                                           // sp mod 16-bytes
-       cmp             r1, #4                                                          // need space for the sp on the stack
-       addlt   r1, r1, #0x10                                           // make room if needed, but keep stack aligned
-       mov             r2,     sp                                                              // get current sp
-       sub             sp, sp, r1                                                      // align stack
-       str             r2, [sp]                                                        // store previous sp on stack
-#endif
-
+       ALIGN_STACK r2, r3
        bl              EXT(sleh_undef)                                         // Call second level handler
-
-#if __BIGGEST_ALIGNMENT__ > 4
-       ldr             sp, [sp]                                                        // restore stack
-#endif
+       UNALIGN_STACK
 
 #if __ARM_USER_PROTECT__
        mrc             p15, 0, r9, c13, c0, 4              // Read TPIDRPRW
@@ -500,6 +516,7 @@ swi_from_kernel:
        str             r0, [sp, SS_SP]                                         // Save supervisor mode sp
        str             lr, [sp, SS_LR]                     // Save supervisor mode lr
 
+       ALIGN_STACK r0, r1
        adr             r0, L_kernel_swi_panic_str                      // Load panic messages and panic()
        blx             EXT(panic)
        b               .
@@ -785,6 +802,7 @@ cache_trap_error:
        mov             r1, sp
        str             r2, [sp]
        str             r3, [sp, #4]
+       ALIGN_STACK r2, r3
        mov             r2, #2
        bl              EXT(exception_triage)
        b               .
@@ -817,13 +835,10 @@ L_kernel_swi_panic_str:
        .globl EXT(fleh_prefabt)
        
 LEXT(fleh_prefabt)
+VERIFY_EXCEPTION_MODE PSR_ABT_MODE
        sub             lr, lr, #4
-       
-       mrs             sp, spsr                                                        // For check the previous mode
-       tst             sp, #0x0f                                                       // Is it from user?
-       bne             prefabt_from_kernel
 
-prefabt_from_user:     
+IF_USERMODE_EXCEPTION prefabt
        mrc             p15, 0, sp, c13, c0, 4                          // Read TPIDRPRW
        add             sp, sp, ACT_PCBDATA                                     // Get User PCB
 
@@ -842,7 +857,6 @@ prefabt_from_user:
        mrs     r4, spsr
        str     r4, [sp, SS_CPSR]                                       // Save user mode cpsr
 
-       mrs             r4, cpsr                                                        // Read cpsr
        cpsid   i, #PSR_SVC_MODE
        mrs             r3, cpsr                                                        // Read cpsr
        msr             spsr_cxsf, r3                       // Set spsr(svc mode cpsr)
@@ -862,9 +876,6 @@ prefabt_from_user:
        mcr             p15, 0, r3, c13, c0, 1                          // Set CONTEXTIDR
        isb
 #endif
-       and             r0, r4, #PSR_MODE_MASK                          // Extract current mode
-       cmp             r0, #PSR_ABT_MODE                                       // Check abort mode
-       bne             EXT(ExceptionVectorPanic)
 
        mvn             r0, #0
        str             r0, [r9, TH_IOTIER_OVERRIDE]                    // Reset IO tier override to -1 before handling abort from userspace
@@ -880,14 +891,7 @@ prefabt_from_user:
                                                                                                // Sleh will enable interrupt
        b               load_and_go_user
 
-prefabt_from_kernel:
-       mrs             sp, cpsr                                                        // Read cpsr
-       and             sp, sp, #PSR_MODE_MASK                          // Extract current mode
-       cmp             sp, #PSR_ABT_MODE                                       // Check abort mode
-       movne   r0, sp
-       bne             EXT(ExceptionVectorPanic)
-       mrs             sp, spsr                                                        // Check the previous mode
-
+ELSE_IF_KERNELMODE_EXCEPTION prefabt
        /*
         * We have a kernel stack already, and I will use it to save contexts:
         *     ------------------
@@ -898,8 +902,6 @@ prefabt_from_kernel:
         *
         * IRQ is disabled
         */
-       cpsid   i, #PSR_SVC_MODE
-
        sub     sp, sp, EXC_CTX_SIZE
        stmia   sp, {r0-r12}
        add             r0, sp, EXC_CTX_SIZE
@@ -929,42 +931,23 @@ prefabt_from_kernel:
        mcr             p15, 0, r3, c13, c0, 1                          // Set CONTEXTIDR
        isb
 #endif
-       mov     ip, sp
 
-       cpsid   i, #PSR_ABT_MODE
-
-       str             lr, [ip, SS_PC]                                         // Save pc to pc and
+       mrs             r4, lr_abt
+       str             r4, [sp, SS_PC]                                 // Save pc
 
        mrc             p15, 0, r5, c6, c0, 2                           // Read IFAR
-       str             r5, [ip, SS_VADDR]                                      // and fault address of pcb
+       str             r5, [sp, SS_VADDR]                                      // and fault address of pcb
        mrc             p15, 0, r5, c5, c0, 1                           // Read (instruction) Fault Status
-       str             r5, [ip, SS_STATUS]                                     // Save fault status register to pcb
-
-       mrs             r4, spsr
-       str             r4, [ip, SS_CPSR]       
-
-       cpsid   i, #PSR_SVC_MODE
+       str             r5, [sp, SS_STATUS]                                     // Save fault status register to pcb
 
-       mov     r0, sp
-
-/*
- * For armv7k ABI, the stack needs to be 16-byte aligned
- */
-#if __BIGGEST_ALIGNMENT__ > 4
-       and     r1, sp, #0x0F                                           // sp mod 16-bytes
-       cmp             r1, #4                                                          // need space for the sp on the stack
-       addlt   r1, r1, #0x10                                           // make room if needed, but keep stack aligned
-       mov             r2,     sp                                                              // get current sp
-       sub             sp, sp, r1                                                      // align stack
-       str             r2, [sp]                                                        // store previous sp on stack
-#endif
+       mrs             r4, spsr_abt
+       str             r4, [sp, SS_CPSR]       
 
+       mov             r0, sp
+       ALIGN_STACK r1, r2
        mov             r1, T_PREFETCH_ABT                                      // Pass abort type
        bl              EXT(sleh_abort)                                         // Call second level handler
-
-#if __BIGGEST_ALIGNMENT__ > 4
-       ldr             sp, [sp]                                                        // restore stack
-#endif
+       UNALIGN_STACK
 
        mrc             p15, 0, r9, c13, c0, 4                          // Read TPIDRPRW
 #if __ARM_USER_PROTECT__
@@ -992,13 +975,9 @@ prefabt_from_kernel:
        .globl EXT(fleh_dataabt)
        
 LEXT(fleh_dataabt)
+VERIFY_EXCEPTION_MODE PSR_ABT_MODE
        sub             lr, lr, #8
-       
-       mrs             sp, spsr                                                        // For check the previous mode
-       tst             sp, #0x0f                                                       // Is it from kernel?
-       bne             dataabt_from_kernel
-
-dataabt_from_user:     
+IF_USERMODE_EXCEPTION dataabt
        mrc             p15, 0, sp, c13, c0, 4                          // Read TPIDRPRW
        add             sp, sp, ACT_PCBDATA                                     // Get User PCB
 
@@ -1019,7 +998,6 @@ dataabt_from_user:
        str             r5, [sp, SS_STATUS]                                     // Save fault status register to pcb
        str             r6, [sp, SS_VADDR]                                      // Save fault address to pcb
 
-       mrs             r4, cpsr                                                        // Read cpsr
        cpsid   i, #PSR_SVC_MODE
        mrs             r3, cpsr                                                        // Read cpsr
        msr             spsr_cxsf, r3                       // Set spsr(svc mode cpsr)
@@ -1039,9 +1017,6 @@ dataabt_from_user:
        mcr             p15, 0, r3, c13, c0, 1                          // Set CONTEXTIDR
        isb
 #endif
-       and             r0, r4, #PSR_MODE_MASK                          // Extract current mode
-       cmp             r0, #PSR_ABT_MODE                                       // Check abort mode
-       bne             EXT(ExceptionVectorPanic)
 
        mvn             r0, #0
        str             r0, [r9, TH_IOTIER_OVERRIDE]                    // Reset IO tier override to -1 before handling abort from userspace
@@ -1057,14 +1032,7 @@ dataabt_from_user:
                                                                                                // Sleh will enable irq
        b               load_and_go_user
 
-dataabt_from_kernel:   
-       mrs             sp, cpsr                                                        // Read cpsr
-       and             sp, sp, #PSR_MODE_MASK                          // Extract current mode
-       cmp             sp, #PSR_ABT_MODE                                       // Check abort mode
-       movne   r0, sp
-       bne             EXT(ExceptionVectorPanic)
-       mrs             sp, spsr                                                        // Check the previous mode
-
+ELSE_IF_KERNELMODE_EXCEPTION dataabt
        /*
         * We have a kernel stack already, and I will use it to save contexts:
         *     ------------------
@@ -1075,8 +1043,6 @@ dataabt_from_kernel:
         *
         * IRQ is disabled
         */
-       cpsid   i, #PSR_SVC_MODE
-
        sub     sp, sp, EXC_CTX_SIZE
        stmia   sp, {r0-r12}
        add             r0, sp, EXC_CTX_SIZE
@@ -1095,15 +1061,10 @@ dataabt_from_kernel:
        fmxr            fpscr, r4                                       // And shove it into FPSCR
 #endif
 
-       mov     ip, sp
-
-       cpsid   i, #PSR_ABT_MODE
-
-       str             lr, [ip, SS_PC]
-       mrs             r4, spsr
-       str             r4, [ip, SS_CPSR]       
-
-       cpsid   i, #PSR_SVC_MODE
+       mrs             r4, lr_abt
+       str             r4, [sp, SS_PC]
+       mrs             r4, spsr_abt
+       str             r4, [sp, SS_CPSR]       
 
 #if __ARM_USER_PROTECT__
        mrc             p15, 0, r10, c2, c0, 0                          // Get TTBR0
@@ -1123,25 +1084,10 @@ dataabt_from_kernel:
        str             r6, [sp, SS_VADDR]                                      // Save fault address to pcb
 
        mov             r0, sp                                                          // Argument
-
-/*
- * For armv7k ABI, the stack needs to be 16-byte aligned
- */
-#if __BIGGEST_ALIGNMENT__ > 4
-       and     r1, sp, #0x0F                                           // sp mod 16-bytes
-       cmp             r1, #4                                                          // need space for the sp on the stack
-       addlt   r1, r1, #0x10                                           // make room if needed, but keep stack aligned
-       mov             r2,     sp                                                              // get current sp
-       sub             sp, sp, r1                                                      // align stack
-       str             r2, [sp]                                                        // store previous sp on stack
-#endif
-
+       ALIGN_STACK r1, r2
        mov             r1, T_DATA_ABT                                          // Pass abort type
        bl              EXT(sleh_abort)                                         // Call second level handler
-
-#if __BIGGEST_ALIGNMENT__ > 4
-       ldr             sp,     [sp]                                                    // restore stack (removed align padding)
-#endif
+       UNALIGN_STACK
 
        mrc             p15, 0, r9, c13, c0, 4                          // Read TPIDRPRW
 #if __ARM_USER_PROTECT__
@@ -1188,24 +1134,9 @@ load_and_go_sys:
        ldr             lr, [sp, SS_LR]                                                 // Restore the link register
        stmfd           sp!, {r7, lr}                                                   // Push a fake frame
 
-       /* TODO: Should this be setting r7?  I think so. */
-       mov             r7, sp                                                  // Set the frame pointer
-
-#if __BIGGEST_ALIGNMENT__ > 4
-       and     r2, sp, #0x0F                                           // sp mod 16-bytes
-       cmp             r2, #4                                                          // need space for the sp on the stack
-       addlt   r2, r2, #0x10                                           // make room if needed, but keep stack aligned
-       mov             r3,     sp                                                              // get current sp
-       sub             sp, sp, r2                                                      // align stack
-       str             r3, [sp]                                                        // store previous sp on stack
-#endif
-
+       ALIGN_STACK r2, r3
        bl              EXT(ast_taken_kernel)                           // Handle AST_URGENT
-
-#if __BIGGEST_ALIGNMENT__ > 4
-       ldr             sp, [sp]
-#endif
-
+       UNALIGN_STACK
 
        ldmfd           sp!, {r7, lr}                                                   // Pop the fake frame
        mrc             p15, 0, r9, c13, c0, 4                          // Reload r9 from TPIDRPRW
@@ -1786,11 +1717,14 @@ LEXT(fleh_dec)
        mcr             p15, 0, r3, c13, c0, 1                          // Set CONTEXTIDR
        isb
 #endif
+
+       ALIGN_STACK r0, r1
        mov             r0, r8                                                          // Get current cpu in arg 0
        mov             r1, SIGPdec                                                     // Decrementer signal in arg1
        mov             r2, #0
        mov             r3, #0
        bl              EXT(cpu_signal)                                         // Call cpu_signal
+       UNALIGN_STACK
 
        mrc             p15, 0, r9, c13, c0, 4                          // Read TPIDRPRW
 
@@ -1818,6 +1752,7 @@ LEXT(fleh_dec)
        cpsid   i, #PSR_IRQ_MODE
        cpsie   f
        mov             sp, r6                                                          // Restore the stack pointer
+       ALIGN_STACK r2, r3
        msr             spsr_cxsf, r4                                           // Restore the spsr
        ldr             r2, [r9, ACT_PREEMPT_CNT]           // Load preemption count
        add             r2, r2, #1                                                      // Increment count
@@ -1864,6 +1799,7 @@ LEXT(fleh_dec)
        movs    r4, r4
        COND_EXTERN_BLNE(interrupt_trace_exit)
 #endif
+       UNALIGN_STACK
 
        mrc             p15, 0, r9, c13, c0, 4                          // Reload r9 from TPIDRPRW
 
@@ -1924,21 +1860,8 @@ load_and_go_user:
        cmp             r5, #0                                                          // Test if ASTs pending
        beq             return_to_user_now                                      // Branch if no ASTs
 
-#if __BIGGEST_ALIGNMENT__ > 4
-       and     r2, sp, #0x0F                                           // sp mod 16-bytes
-       cmp             r2, #4                                                          // need space for the sp on the stack
-       addlt   r2, r2, #0x10                                           // make room if needed, but keep stack aligned
-       mov             r3,     sp                                                              // get current sp
-       sub             sp, sp, r2                                                      // align stack
-       str             r3, [sp]                                                        // store previous sp on stack
-#endif
-
        bl              EXT(ast_taken_user)                                     // Handle all ASTs (may continue via thread_exception_return)
 
-#if __BIGGEST_ALIGNMENT__ > 4
-       ldr     sp, [sp]                                                // Restore the stack pointer
-#endif
-
        mrc             p15, 0, r9, c13, c0, 4                          // Reload r9 from TPIDRPRW
        b       load_and_go_user                                                // Loop back
 
@@ -2028,6 +1951,7 @@ L_evimpanic_str:
 
 LEXT(ExceptionVectorPanic)
        cpsid i, #PSR_SVC_MODE
+       ALIGN_STACK r1, r2
        mov             r1, r0
        adr             r0, L_evimpanic_str
        blx             EXT(panic)
index bc3e4f8ebdd1c1d8f53af60d46472d2e11936eff..83e60754060eb41e3f964345e488b80e01b95412 100644 (file)
@@ -544,9 +544,6 @@ ml_processor_register(
 
        this_cpu_datap->cpu_id = in_processor_info->cpu_id;
 
-       this_cpu_datap->cpu_chud = chudxnu_cpu_alloc(is_boot_cpu);
-       if (this_cpu_datap->cpu_chud == (void *)NULL)
-               goto processor_register_error;
        this_cpu_datap->cpu_console_buf = console_cpu_alloc(is_boot_cpu);
        if (this_cpu_datap->cpu_console_buf == (void *)(NULL))
                goto processor_register_error;
@@ -604,8 +601,6 @@ processor_register_error:
 #if KPC
        kpc_unregister_cpu(this_cpu_datap);
 #endif
-       if (this_cpu_datap->cpu_chud != (void *)NULL)
-               chudxnu_cpu_free(this_cpu_datap->cpu_chud);
        if (!is_boot_cpu)
                cpu_data_free(this_cpu_datap);
        return KERN_FAILURE;
index 3e46c61e187fd3c466bf69c49273481c600658f4..cee6477b1e391192b9fc095675b9b04af9bb65ea 100644 (file)
@@ -629,6 +629,26 @@ struct perfcontrol_work_interval {
 };
 typedef struct perfcontrol_work_interval *perfcontrol_work_interval_t;
 
+typedef enum {
+       WORK_INTERVAL_START,
+       WORK_INTERVAL_UPDATE,
+       WORK_INTERVAL_FINISH
+} work_interval_ctl_t;
+
+struct perfcontrol_work_interval_instance {
+       work_interval_ctl_t     ctl;
+       uint32_t                create_flags;
+       uint64_t                complexity;
+       uint64_t                thread_id;
+       uint64_t                work_interval_id;
+       uint64_t                instance_id; /* out: start, in: update/finish */
+       uint64_t                start;
+       uint64_t                finish;
+       uint64_t                deadline;
+       uint64_t                thread_group_id;
+       void                    *thread_group_data;
+};
+typedef struct perfcontrol_work_interval_instance *perfcontrol_work_interval_instance_t;
 
 /* 
  * Structure to export per-CPU counters as part of the CLPC callout. 
@@ -727,6 +747,11 @@ typedef void (*sched_perfcontrol_max_runnable_latency_t)(perfcontrol_max_runnabl
  */
 typedef void (*sched_perfcontrol_work_interval_notify_t)(perfcontrol_state_t, perfcontrol_work_interval_t);
 
+/*
+ * Start, update and finish work interval instance with optional complexity estimate.
+ */
+typedef void (*sched_perfcontrol_work_interval_ctl_t)(perfcontrol_state_t, perfcontrol_work_interval_instance_t);
+
 /*
  * These callbacks are used when thread groups are added, removed or properties
  * updated.
@@ -778,7 +803,6 @@ typedef void (*sched_perfcontrol_state_update_t)(
        perfcontrol_event event, uint32_t cpu_id, uint64_t timestamp, uint32_t flags,
        struct perfcontrol_thread_data *thr_data, __unused void *unused);
 
-
 /*
  * Callers should always use the CURRENT version so that the kernel can detect both older
  * and newer structure layouts. New callbacks should always be added at the end of the
@@ -794,6 +818,7 @@ typedef void (*sched_perfcontrol_state_update_t)(
 #define SCHED_PERFCONTROL_CALLBACKS_VERSION_4 (4) /* up-to deadline_passed */
 #define SCHED_PERFCONTROL_CALLBACKS_VERSION_5 (5) /* up-to state_update */
 #define SCHED_PERFCONTROL_CALLBACKS_VERSION_6 (6) /* up-to thread_group_flags_update */
+#define SCHED_PERFCONTROL_CALLBACKS_VERSION_7 (7) /* up-to work_interval_ctl */
 #define SCHED_PERFCONTROL_CALLBACKS_VERSION_CURRENT SCHED_PERFCONTROL_CALLBACKS_VERSION_6
 
 struct sched_perfcontrol_callbacks {
@@ -809,6 +834,7 @@ struct sched_perfcontrol_callbacks {
        sched_perfcontrol_csw_t                       csw;
        sched_perfcontrol_state_update_t              state_update;
        sched_perfcontrol_thread_group_flags_update_t thread_group_flags_update;
+       sched_perfcontrol_work_interval_ctl_t         work_interval_ctl;
 };
 typedef struct sched_perfcontrol_callbacks *sched_perfcontrol_callbacks_t;
 
index 764fb97e0ceef68ecb907e35636f91b1a9acac3e..9afa6a74f335a7c473be42384852a358fcb32bb6 100644 (file)
@@ -81,7 +81,14 @@ sched_perfcontrol_max_runnable_latency_default(perfcontrol_max_runnable_latency_
 }
 
 static void
-sched_perfcontrol_work_interval_notify_default(perfcontrol_state_t thread_state __unused, perfcontrol_work_interval_t work_interval __unused)
+sched_perfcontrol_work_interval_notify_default(perfcontrol_state_t thread_state __unused,
+                                              perfcontrol_work_interval_t work_interval __unused)
+{
+}
+
+static void
+sched_perfcontrol_work_interval_ctl_default(perfcontrol_state_t thread_state __unused,
+                                           perfcontrol_work_interval_instance_t instance __unused)
 {
 }
 
@@ -115,6 +122,7 @@ sched_perfcontrol_thread_group_deinit_t         sched_perfcontrol_thread_group_d
 sched_perfcontrol_thread_group_flags_update_t   sched_perfcontrol_thread_group_flags_update = sched_perfcontrol_thread_group_default;
 sched_perfcontrol_max_runnable_latency_t        sched_perfcontrol_max_runnable_latency = sched_perfcontrol_max_runnable_latency_default;
 sched_perfcontrol_work_interval_notify_t        sched_perfcontrol_work_interval_notify = sched_perfcontrol_work_interval_notify_default;
+sched_perfcontrol_work_interval_ctl_t           sched_perfcontrol_work_interval_ctl = sched_perfcontrol_work_interval_ctl_default;
 sched_perfcontrol_deadline_passed_t             sched_perfcontrol_deadline_passed = sched_perfcontrol_deadline_passed_default;
 sched_perfcontrol_csw_t                         sched_perfcontrol_csw = sched_perfcontrol_csw_default;
 sched_perfcontrol_state_update_t                sched_perfcontrol_state_update = sched_perfcontrol_state_update_default;
@@ -131,6 +139,14 @@ sched_perfcontrol_register_callbacks(sched_perfcontrol_callbacks_t callbacks, un
        if (callbacks) {
 
 
+               if (callbacks->version >= SCHED_PERFCONTROL_CALLBACKS_VERSION_7) {
+                       if (callbacks->work_interval_ctl != NULL) {
+                               sched_perfcontrol_work_interval_ctl = callbacks->work_interval_ctl;
+                       } else {
+                               sched_perfcontrol_work_interval_ctl = sched_perfcontrol_work_interval_ctl_default;
+                       }
+               }
+
                if (callbacks->version >= SCHED_PERFCONTROL_CALLBACKS_VERSION_5) {
                        if (callbacks->csw != NULL) {
                                sched_perfcontrol_csw = callbacks->csw;
@@ -192,6 +208,7 @@ sched_perfcontrol_register_callbacks(sched_perfcontrol_callbacks_t callbacks, un
                sched_perfcontrol_thread_group_flags_update = sched_perfcontrol_thread_group_default;
                sched_perfcontrol_max_runnable_latency = sched_perfcontrol_max_runnable_latency_default;
                sched_perfcontrol_work_interval_notify = sched_perfcontrol_work_interval_notify_default;
+               sched_perfcontrol_work_interval_ctl = sched_perfcontrol_work_interval_ctl_default;
                sched_perfcontrol_csw = sched_perfcontrol_csw_default;
                sched_perfcontrol_state_update = sched_perfcontrol_state_update_default;
        }
@@ -432,6 +449,7 @@ machine_work_interval_notify(thread_t thread,
        sched_perfcontrol_work_interval_notify(state, &work_interval);
 }
 
+
 void
 machine_perfcontrol_deadline_passed(uint64_t deadline)
 {
index ad9fd23ea9686892bedee1776341bef98115012c..1ae4b3c5586c9fd8f75809adff1335808ca22fe6 100644 (file)
@@ -330,7 +330,7 @@ do_print_all_backtraces(
 #if defined(XNU_TARGET_OS_BRIDGE)
                paniclog_append_noflush("PCIeUp link state: ");
                if (PE_pcie_stashed_link_state != UINT32_MAX) {
-                       paniclog_append_noflush("0x%x", PE_pcie_stashed_link_state);
+                       paniclog_append_noflush("0x%x\n", PE_pcie_stashed_link_state);
                } else {
                        paniclog_append_noflush("not available\n");
                }
index 990ab667d14fe5c595a0b8ad17d5e153b7da8b1f..a62fd171e6ebd18a3292c61350c938458b6df509 100644 (file)
@@ -2988,6 +2988,11 @@ pmap_bootstrap(
                           &pmap_stats_assert,
                           sizeof (pmap_stats_assert));
 #endif /* MACH_ASSERT */
+
+#if KASAN
+       /* Shadow the CPU copy windows, as they fall outside of the physical aperture */
+       kasan_map_shadow(CPUWINDOWS_BASE, CPUWINDOWS_TOP - CPUWINDOWS_BASE, true);
+#endif /* KASAN */
 }
 
 
@@ -4319,7 +4324,8 @@ pmap_remove_range_options(
                /* sanity checks... */
 #if MACH_ASSERT
                if (pmap->stats.internal < num_internal) {
-                       if ((! pmap_stats_assert) ||
+                       if ((! pmap_stats_assert ||
+                            ! pmap->pmap_stats_assert) ||
                            (pmap->stats.internal + pmap->stats.reusable) ==
                            (num_internal + num_reusable)) {
                                num_reusable_mismatch++;
@@ -5524,16 +5530,17 @@ pmap_enter_options_internal(
        boolean_t wired,
        unsigned int options)
 {
-       pmap_paddr_t    pa = ptoa(pn);
-       pt_entry_t              pte;
-       pt_entry_t              spte;
-       pt_entry_t              *pte_p;
-       pv_entry_t              *pve_p;
-       boolean_t               set_NX;
-       boolean_t               set_XO = FALSE;
-       boolean_t               refcnt_updated;
-       unsigned int    wimg_bits;
-       boolean_t               was_compressed, was_alt_compressed;
+       pmap_paddr_t    pa = ptoa(pn);
+       pt_entry_t      pte;
+       pt_entry_t      spte;
+       pt_entry_t      *pte_p;
+       pv_entry_t      *pve_p;
+       boolean_t       set_NX;
+       boolean_t       set_XO = FALSE;
+       boolean_t       refcnt_updated;
+       boolean_t       wiredcnt_updated;
+       unsigned int    wimg_bits;
+       boolean_t       was_compressed, was_alt_compressed;
 
        if ((v) & PAGE_MASK) {
                panic("pmap_enter_options() pmap %p v 0x%llx\n",
@@ -5562,6 +5569,7 @@ pmap_enter_options_internal(
        assert(pn != vm_page_fictitious_addr);
 
        refcnt_updated = FALSE;
+       wiredcnt_updated = FALSE;
        pve_p = PV_ENTRY_NULL;
        was_compressed = FALSE;
        was_alt_compressed = FALSE;
@@ -5757,16 +5765,17 @@ Pmap_enter_retry:
        pte |= ARM_PTE_AF;
 
        volatile uint16_t *refcnt = NULL;
+       volatile uint16_t *wiredcnt = NULL;
        if (pmap != kernel_pmap) {
                refcnt = &(ptep_get_ptd(pte_p)->pt_cnt[ARM_PT_DESC_INDEX(pte_p)].refcnt);
-               /* Mark the PT page active to keep it from being reclaimed.  We need this because
+               wiredcnt = &(ptep_get_ptd(pte_p)->pt_cnt[ARM_PT_DESC_INDEX(pte_p)].wiredcnt);
+               /* Bump the wired count to keep the PTE page from being reclaimed.  We need this because
                 * we may drop the PVH and pmap locks later in pmap_enter() if we need to allocate
-                * a new PV entry.  Note that setting this high bit (0x4000) can temporarily
-                * prevent the refcount underflow checks in pmap_page_protect() and pmap_remove() from
-                * working.  If an underflow should happen during this window, we'll instead get a
-                * refcount along the lines of 0x3FFF, which will produce a later panic on non-zero
-                * refcount in pmap_pages_reclaim() or pmap_tt_deallocate(). */
-               OSBitOrAtomic16(PT_DESC_REFCOUNT, refcnt);
+                * a new PV entry. */
+               if (!wiredcnt_updated) {
+                       OSAddAtomic16(1, (volatile int16_t*)wiredcnt);
+                       wiredcnt_updated = TRUE;
+               }
                if (!refcnt_updated) {
                        OSAddAtomic16(1, (volatile int16_t*)refcnt);
                        refcnt_updated = TRUE;
@@ -5794,7 +5803,7 @@ Pmap_enter_loop:
                         */
                        if (refcnt != NULL) {
                                assert(refcnt_updated);
-                               if (OSAddAtomic16(-1, (volatile int16_t*)refcnt) <= (int16_t)PT_DESC_REFCOUNT)
+                               if (OSAddAtomic16(-1, (volatile int16_t*)refcnt) <= 0)
                                        panic("pmap_enter(): over-release of ptdp %p for pte %p\n", ptep_get_ptd(pte_p), pte_p);
                        }
                        UNLOCK_PVH(pai);
@@ -5802,7 +5811,7 @@ Pmap_enter_loop:
                } else if (pte_to_pa(*pte_p) == pa) {
                        if (refcnt != NULL) {
                                assert(refcnt_updated);
-                               if (OSAddAtomic16(-1, (volatile int16_t*)refcnt) <= (int16_t)PT_DESC_REFCOUNT)
+                               if (OSAddAtomic16(-1, (volatile int16_t*)refcnt) <= 0)
                                        panic("pmap_enter(): over-release of ptdp %p for pte %p\n", ptep_get_ptd(pte_p), pte_p);
                        }
                        pmap_enter_pte(pmap, pte_p, pte, v);
@@ -5974,19 +5983,20 @@ Pmap_enter_loop:
 Pmap_enter_return:
 
 #if CONFIG_PGTRACE
-    if (pgtrace_enabled) {
-        // Clone and invalidate original mapping if eligible
-        for (int i = 0; i < PAGE_RATIO; i++) {
-            pmap_pgtrace_enter_clone(pmap, v + ARM_PGBYTES*i, 0, 0);
-        }
-    }
+       if (pgtrace_enabled) {
+               // Clone and invalidate original mapping if eligible
+               for (int i = 0; i < PAGE_RATIO; i++) {
+                       pmap_pgtrace_enter_clone(pmap, v + ARM_PGBYTES*i, 0, 0);
+               }
+       }
 #endif
 
        if (pve_p != PV_ENTRY_NULL)
                pv_free(pve_p);
 
-       if (refcnt != NULL)
-               OSBitAndAtomic16(~PT_DESC_REFCOUNT, refcnt); // clear active marker
+       if (wiredcnt_updated && (OSAddAtomic16(-1, (volatile int16_t*)wiredcnt) <= 0))
+               panic("pmap_enter(): over-unwire of ptdp %p for pte %p\n", ptep_get_ptd(pte_p), pte_p);
+
        PMAP_UNLOCK(pmap);
 
        return KERN_SUCCESS;
@@ -9142,12 +9152,18 @@ vm_map_offset_t pmap_max_offset(
                        max_offset_ret = min_max_offset;
                }
        } else if (option == ARM_PMAP_MAX_OFFSET_JUMBO) {
-               max_offset_ret = 0x0000000518000000ULL;     // Max offset is 20.375GB for pmaps with special "jumbo" blessing
+               if (arm64_pmap_max_offset_default) {
+                       // Allow the boot-arg to override jumbo size
+                       max_offset_ret = arm64_pmap_max_offset_default;
+               } else {
+                       max_offset_ret = MACH_VM_MAX_ADDRESS;     // Max offset is MACH_VM_MAX_ADDRESS for pmaps with special "jumbo" blessing
+               }
        } else {
                panic("pmap_max_offset illegal option 0x%x\n", option);
        }
 
        assert(max_offset_ret >= min_max_offset);
+       assert(max_offset_ret <= MACH_VM_MAX_ADDRESS);
        return max_offset_ret;
 #else
        if (option == ARM_PMAP_MAX_OFFSET_DEFAULT) {
@@ -9168,6 +9184,7 @@ vm_map_offset_t pmap_max_offset(
                panic("pmap_max_offset illegal option 0x%x\n", option);
        }
 
+       assert(max_offset_ret <= VM_MAX_ADDRESS);
        return max_offset_ret;
 #endif
 }
@@ -9605,7 +9622,8 @@ pmap_check_ledgers(
        }
 
        if (do_panic) {
-               if (pmap_ledgers_panic) {
+               if (pmap_ledgers_panic &&
+                   pmap->pmap_stats_assert) {
                        panic("pmap_destroy(%p) %d[%s] has imbalanced ledgers\n",
                              pmap, pid, procname);
                } else {
@@ -10624,7 +10642,7 @@ pmap_query_page_info_internal(
                        pve_p = pvh_list(pv_h);
                        while (pve_p != PV_ENTRY_NULL &&
                               pve_get_ptep(pve_p) != pte) {
-                               pve_p = pvh_list(pv_h);
+                               pve_p = PVE_NEXT_PTR(pve_next(pve_p));
                        }
                }
                if (IS_ALTACCT_PAGE(pai, pve_p)) {
index 9dc5e2ec8c81b9c14dc1767a38709e2b948858d4..28a99e3f56d268e4eea6905df1b295d82bff9bce 100644 (file)
 #define ARM_DBG_CR_SECURITY_STATE_BOTH      (0 << 14)
 #define ARM_DBG_CR_SECURITY_STATE_NONSECURE (1 << 14)
 #define ARM_DBG_CR_SECURITY_STATE_SECURE    (2 << 14)
+#define ARM_DBG_CR_HIGHER_MODE_MASK         (1 << 13)   /* BCR & WCR */
+#define ARM_DBG_CR_HIGHER_MODE_ENABLE       (1 << 13)
+#define ARM_DBG_CR_HIGHER_MODE_DISABLE      (0 << 13)
 #define ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK 0x00001FE0  /* WCR only  */
 #define ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK 0x000001E0  /* BCR & WCR */
 #define ARM_DBGWCR_ACCESS_CONTROL_MASK      (3 << 3)    /* WCR only */
 #define ARM_DBCWCR_ACCESS_CONTROL_ANY       (3 << 3)
 #define ARM_DBG_CR_MODE_CONTROL_MASK        (3 << 1)    /* BCR & WCR */
 #define ARM_DBG_CR_MODE_CONTROL_U_S_S       (0 << 1)    /* BCR only  */
-#define ARM_DBG_CR_MODE_CONTROL_PRIVILEDGED (1 << 1)    /* BCR & WCR */
+#define ARM_DBG_CR_MODE_CONTROL_PRIVILEGED  (1 << 1)    /* BCR & WCR */
 #define ARM_DBG_CR_MODE_CONTROL_USER        (2 << 1)    /* BCR & WCR */
 #define ARM_DBG_CR_MODE_CONTROL_ANY         (3 << 1)    /* BCR & WCR */
 #define ARM_DBG_CR_ENABLE_MASK              (1 << 0)    /* BCR & WCR */
index 617c652ab73d7cd4fb6ef789de000cbfd8753bb9..a2c691c740e427d82ed1e6864728662b114f2634 100644 (file)
@@ -103,9 +103,6 @@ void            sleh_abort(struct arm_saved_state *, int);
 static kern_return_t sleh_alignment(struct arm_saved_state *);
 static void    panic_with_thread_kernel_state(const char *msg, arm_saved_state_t *regs);
 
-
-volatile perfCallback    perfTrapHook = NULL;  /* Pointer to CHUD trap hook routine */
-
 int             sleh_alignment_count = 0;
 int             trap_on_alignment_fault = 0;
 
index fe15c273335d5f606a9cf8ca9307d6ee42d59a25..a4caeaa5a69ebfdfa1d505de01a7913b1b2ae629 100644 (file)
@@ -273,12 +273,6 @@ typedef kern_return_t (*perfCallback)(
                                uintptr_t *,
                                      int);
 
-typedef kern_return_t (*perfASTCallback)(ast_t reasons, ast_t *myast);
-
-extern volatile perfCallback perfTrapHook;
-extern volatile perfASTCallback perfASTHook;
-extern volatile perfCallback perfIntHook;
-
 #endif /* !ASSEMBLER && MACH_KERNEL */
 
 #endif /* _ARM_TRAP_H_ */
index 463d390675b21ab345e5563ed9dc767ac20f5a94..ac50fd03774c8865d881e6cc4eb2bb126c03c511 100644 (file)
@@ -222,7 +222,28 @@ LEXT(CleanPoC_DcacheRegion)
        .align 2
        .globl EXT(CleanPoC_DcacheRegion_Force)
 LEXT(CleanPoC_DcacheRegion_Force)
-       b EXT(CleanPoC_DcacheRegion_internal)
+#if defined(APPLE_ARM64_ARCH_FAMILY)
+       PUSH_FRAME
+       stp             x0, x1, [sp, #-16]!
+       bl              EXT(_disable_preemption)
+       isb             sy
+       ARM64_IS_PCORE x15
+       ARM64_READ_EP_SPR x15, x14, ARM64_REG_EHID4, ARM64_REG_HID4
+       and             x14, x14, (~ARM64_REG_HID4_DisDcMVAOps)
+       ARM64_WRITE_EP_SPR x15, x14, ARM64_REG_EHID4, ARM64_REG_HID4
+       isb             sy
+       ldp             x0, x1, [sp], #16
+       bl              EXT(CleanPoC_DcacheRegion_internal)
+       isb             sy
+       orr             x14, x14, ARM64_REG_HID4_DisDcMVAOps
+       ARM64_WRITE_EP_SPR x15, x14, ARM64_REG_EHID4, ARM64_REG_HID4
+       isb             sy
+       bl              EXT(_enable_preemption)
+       POP_FRAME
+       ret
+#else
+       b               EXT(CleanPoC_DcacheRegion_internal)
+#endif // APPLE_ARM64_ARCH_FAMILY
 
 /*
  *     void FlushPoC_Dcache(void)
index ea33d6b42c6a4d64e2cf9b282702dbfa1370bc81..4430d3b5ce0593bbfdaea9ea49d280cdc5a0b3f7 100644 (file)
 .endmacro
 
 #if __ARM_KERNEL_PROTECT__
-       .data
+       .text
        .align 3
        .globl EXT(exc_vectors_table)
 LEXT(exc_vectors_table)
@@ -564,12 +564,38 @@ fleh_dispatch64:
        /* Save arm_saved_state64 */
        SPILL_REGISTERS
 
-       /* If exception is from userspace, zero lr */
-       ldr             w21, [x0, SS64_CPSR]
-       and             x21, x21, #(PSR64_MODE_EL_MASK)
-       cmp             x21, #(PSR64_MODE_EL0)
+       /* If exception is from userspace, zero unused registers */
+       and             x23, x23, #(PSR64_MODE_EL_MASK)
+       cmp             x23, #(PSR64_MODE_EL0)
        bne             1f
-       mov             lr, #0
+
+       mov             x2, xzr
+       mov             x3, xzr
+       mov             x4, xzr
+       mov             x5, xzr
+       mov             x6, xzr
+       mov             x7, xzr
+       mov             x8, xzr
+       mov             x9, xzr
+       mov             x10, xzr
+       mov             x11, xzr
+       mov             x12, xzr
+       mov             x13, xzr
+       mov             x14, xzr
+       mov             x15, xzr
+       mov             x16, xzr
+       mov             x17, xzr
+       mov             x18, xzr
+       mov             x19, xzr
+       mov             x20, xzr
+       /* x21, x22 cleared in common case below */
+       mov             x23, xzr
+       mov             x24, xzr
+       mov             x25, xzr
+       mov             x26, xzr
+       mov             x27, xzr
+       mov             x28, xzr
+       /* fp/lr already cleared by EL0_64_VECTOR */
 1:
 
        mov             x21, x0                                                         // Copy arm_context_t pointer to x21
@@ -885,9 +911,9 @@ check_user_asts:
 
 
 exception_return:
-       msr             DAIFSet, #(DAIFSC_IRQF | DAIFSC_FIQF)   // Disable interrupts
-       mrs             x3, TPIDR_EL1                                           // Load thread pointer
-       mov             sp, x21                                                         // Reload the pcb pointer
+       msr             DAIFSet, #DAIFSC_ALL                            // Disable exceptions
+       mrs             x3, TPIDR_EL1                                   // Load thread pointer
+       mov             sp, x21                                         // Reload the pcb pointer
 
        /* ARM64_TODO Reserve x18 until we decide what to do with it */
        ldr             x0, [x3, TH_CTH_DATA]                           // Load cthread data pointer
index defb3f8376a5fcbd1c8d5c535f35b0c5ee9ad563..f6a5db38c0cca74cbc6cec553feea0922180fcc1 100644 (file)
@@ -942,9 +942,6 @@ ml_processor_register(
 
        this_cpu_datap->cpu_id = in_processor_info->cpu_id;
 
-       this_cpu_datap->cpu_chud = chudxnu_cpu_alloc(is_boot_cpu);
-       if (this_cpu_datap->cpu_chud == (void *)NULL)
-               goto processor_register_error;
        this_cpu_datap->cpu_console_buf = console_cpu_alloc(is_boot_cpu);
        if (this_cpu_datap->cpu_console_buf == (void *)(NULL))
                goto processor_register_error;
@@ -1020,8 +1017,6 @@ processor_register_error:
 #if KPC
        kpc_unregister_cpu(this_cpu_datap);
 #endif
-       if (this_cpu_datap->cpu_chud != (void *)NULL)
-               chudxnu_cpu_free(this_cpu_datap->cpu_chud);
        if (!is_boot_cpu)
                cpu_data_free(this_cpu_datap);
 
index 55d5fe4d93020c717802b5894a04dbfa930d95ec..a6fa9154b603365a6924d851aef6e293064c036f 100644 (file)
@@ -367,14 +367,69 @@ call_continuation(
        Call_continuation(continuation, parameter, wresult, current_thread()->machine.kstackptr);
 }
 
+/* Setting breakpoints in EL1 is effectively a KTRR bypass. The ability to do so is
+ * controlled by MDSCR.KDE. The MSR to set MDSCR must be present to allow
+ * self-hosted user mode debug. Any checks before the MRS can be skipped with ROP,
+ * so we need to put the checks after the MRS where they can't be skipped. That
+ * still leaves a small window if a breakpoint is set on the instruction
+ * immediately after the MRS. To handle that, we also do a check and then set of
+ * the breakpoint control registers. This allows us to guarantee that a given
+ * core will never have both KDE set and a breakpoint targeting EL1.
+ *
+ * If KDE gets set, unset it and then panic */
+static void
+update_mdscr(uint64_t clear, uint64_t set)
+{  
+       uint64_t result = 0;
+       uint64_t tmp1, tmp2;
+       __asm__ volatile(
+               "mrs %[reg], MDSCR_EL1\n"
+               "bic %[reg], %[reg], %[clear]\n"
+               "orr %[reg], %[reg], %[set]\n"
+               "1:\n"
+               "bic %[reg], %[reg], #0x2000\n"
+               "msr MDSCR_EL1, %[reg]\n"
+#if defined(CONFIG_KERNEL_INTEGRITY)
+               /* verify KDE didn't get set (including via ROP)
+                * If set, clear it and then panic */
+               "ands %[tmp], %[reg], #0x2000\n"
+               "orr %[res], %[res], %[tmp]\n"
+               "bne 1b\n"
+#endif
+               : [res] "+r" (result), [tmp] "=r" (tmp1), [reg] "=r" (tmp2)
+               : [clear] "r" (clear), [set] "r" (set) : "x0");
+#if defined(CONFIG_KERNEL_INTEGRITY)
+       if (result)
+               panic("MDSCR.KDE was set: %llx %llx %llx", tmp1, tmp2, result);
+#endif
+}
+
+#define SET_DBGBCRn(n, value, accum) \
+       __asm__ volatile( \
+               "msr DBGBCR" #n "_EL1, %[val]\n" \
+               "orr %[result], %[result], %[val]\n" \
+               : [result] "+r"(accum) : [val] "r"((value)))
+
+#define SET_DBGBVRn(n, value) \
+       __asm__ volatile("msr DBGBVR" #n "_EL1, %0" : : "r"(value))
+
+#define SET_DBGWCRn(n, value, accum) \
+       __asm__ volatile( \
+               "msr DBGWCR" #n "_EL1, %[val]\n" \
+               "orr %[result], %[result], %[val]\n" \
+               : [result] "+r"(accum) : [val] "r"((value)))
+
+#define SET_DBGWVRn(n, value) \
+       __asm__ volatile("msr DBGWVR" #n "_EL1, %0" : : "r"(value))
+
 void arm_debug_set32(arm_debug_state_t *debug_state)
 {
        struct cpu_data         *cpu_data_ptr;
        arm_debug_info_t        *debug_info = arm_debug_info();
-       volatile uint64_t       state;
        boolean_t               intr, set_mde = 0;
        arm_debug_state_t       off_state;
        uint32_t                        i;
+       uint64_t                all_ctrls = 0;
 
        intr = ml_set_interrupts_enabled(FALSE);
        cpu_data_ptr = getCpuDatap();
@@ -389,110 +444,116 @@ void arm_debug_set32(arm_debug_state_t *debug_state)
 
        switch (debug_info->num_breakpoint_pairs) {
        case 16:
-               __asm__ volatile("msr DBGBVR15_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[15]));
-               __asm__ volatile("msr DBGBCR15_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[15]));
+               SET_DBGBVRn(15, (uint64_t)debug_state->uds.ds32.bvr[15]);
+               SET_DBGBCRn(15, (uint64_t)debug_state->uds.ds32.bcr[15], all_ctrls);
        case 15:
-               __asm__ volatile("msr DBGBVR14_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[14]));
-               __asm__ volatile("msr DBGBCR14_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[14]));
+               SET_DBGBVRn(14, (uint64_t)debug_state->uds.ds32.bvr[14]);
+               SET_DBGBCRn(14, (uint64_t)debug_state->uds.ds32.bcr[14], all_ctrls);
        case 14:
-               __asm__ volatile("msr DBGBVR13_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[13]));
-               __asm__ volatile("msr DBGBCR13_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[13]));
+               SET_DBGBVRn(13, (uint64_t)debug_state->uds.ds32.bvr[13]);
+               SET_DBGBCRn(13, (uint64_t)debug_state->uds.ds32.bcr[13], all_ctrls);
        case 13:
-               __asm__ volatile("msr DBGBVR12_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[12]));
-               __asm__ volatile("msr DBGBCR12_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[12]));
+               SET_DBGBVRn(12, (uint64_t)debug_state->uds.ds32.bvr[12]);
+               SET_DBGBCRn(12, (uint64_t)debug_state->uds.ds32.bcr[12], all_ctrls);
        case 12:
-               __asm__ volatile("msr DBGBVR11_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[11]));
-               __asm__ volatile("msr DBGBCR11_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[11]));
+               SET_DBGBVRn(11, (uint64_t)debug_state->uds.ds32.bvr[11]);
+               SET_DBGBCRn(11, (uint64_t)debug_state->uds.ds32.bcr[11], all_ctrls);
        case 11:
-               __asm__ volatile("msr DBGBVR10_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[10]));
-               __asm__ volatile("msr DBGBCR10_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[10]));
+               SET_DBGBVRn(10, (uint64_t)debug_state->uds.ds32.bvr[10]);
+               SET_DBGBCRn(10, (uint64_t)debug_state->uds.ds32.bcr[10], all_ctrls);
        case 10:
-               __asm__ volatile("msr DBGBVR9_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[9]));
-               __asm__ volatile("msr DBGBCR9_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[9]));
+               SET_DBGBVRn(9, (uint64_t)debug_state->uds.ds32.bvr[9]);
+               SET_DBGBCRn(9, (uint64_t)debug_state->uds.ds32.bcr[9], all_ctrls);
        case 9:
-               __asm__ volatile("msr DBGBVR8_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[8]));
-               __asm__ volatile("msr DBGBCR8_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[8]));
+               SET_DBGBVRn(8, (uint64_t)debug_state->uds.ds32.bvr[8]);
+               SET_DBGBCRn(8, (uint64_t)debug_state->uds.ds32.bcr[8], all_ctrls);
        case 8:
-               __asm__ volatile("msr DBGBVR7_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[7]));
-               __asm__ volatile("msr DBGBCR7_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[7]));
+               SET_DBGBVRn(7, (uint64_t)debug_state->uds.ds32.bvr[7]);
+               SET_DBGBCRn(7, (uint64_t)debug_state->uds.ds32.bcr[7], all_ctrls);
        case 7:
-               __asm__ volatile("msr DBGBVR6_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[6]));
-               __asm__ volatile("msr DBGBCR6_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[6]));
+               SET_DBGBVRn(6, (uint64_t)debug_state->uds.ds32.bvr[6]);
+               SET_DBGBCRn(6, (uint64_t)debug_state->uds.ds32.bcr[6], all_ctrls);
        case 6:
-               __asm__ volatile("msr DBGBVR5_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[5]));
-               __asm__ volatile("msr DBGBCR5_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[5]));
+               SET_DBGBVRn(5, (uint64_t)debug_state->uds.ds32.bvr[5]);
+               SET_DBGBCRn(5, (uint64_t)debug_state->uds.ds32.bcr[5], all_ctrls);
        case 5:
-               __asm__ volatile("msr DBGBVR4_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[4]));
-               __asm__ volatile("msr DBGBCR4_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[4]));
+               SET_DBGBVRn(4, (uint64_t)debug_state->uds.ds32.bvr[4]);
+               SET_DBGBCRn(4, (uint64_t)debug_state->uds.ds32.bcr[4], all_ctrls);
        case 4:
-               __asm__ volatile("msr DBGBVR3_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[3]));
-               __asm__ volatile("msr DBGBCR3_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[3]));
+               SET_DBGBVRn(3, (uint64_t)debug_state->uds.ds32.bvr[3]);
+               SET_DBGBCRn(3, (uint64_t)debug_state->uds.ds32.bcr[3], all_ctrls);
        case 3:
-               __asm__ volatile("msr DBGBVR2_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[2]));
-               __asm__ volatile("msr DBGBCR2_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[2]));
+               SET_DBGBVRn(2, (uint64_t)debug_state->uds.ds32.bvr[2]);
+               SET_DBGBCRn(2, (uint64_t)debug_state->uds.ds32.bcr[2], all_ctrls);
        case 2:
-               __asm__ volatile("msr DBGBVR1_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[1]));
-               __asm__ volatile("msr DBGBCR1_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[1]));
+               SET_DBGBVRn(1, (uint64_t)debug_state->uds.ds32.bvr[1]);
+               SET_DBGBCRn(1, (uint64_t)debug_state->uds.ds32.bcr[1], all_ctrls);
        case 1:
-               __asm__ volatile("msr DBGBVR0_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bvr[0]));
-               __asm__ volatile("msr DBGBCR0_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.bcr[0]));
+               SET_DBGBVRn(0, (uint64_t)debug_state->uds.ds32.bvr[0]);
+               SET_DBGBCRn(0, (uint64_t)debug_state->uds.ds32.bcr[0], all_ctrls);
        default:
                break;
        }
 
        switch (debug_info->num_watchpoint_pairs) {
        case 16:
-               __asm__ volatile("msr DBGWVR15_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[15]));
-               __asm__ volatile("msr DBGWCR15_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[15]));
+               SET_DBGWVRn(15, (uint64_t)debug_state->uds.ds32.wvr[15]);
+               SET_DBGWCRn(15, (uint64_t)debug_state->uds.ds32.wcr[15], all_ctrls);
        case 15:
-               __asm__ volatile("msr DBGWVR14_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[14]));
-               __asm__ volatile("msr DBGWCR14_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[14]));
+               SET_DBGWVRn(14, (uint64_t)debug_state->uds.ds32.wvr[14]);
+               SET_DBGWCRn(14, (uint64_t)debug_state->uds.ds32.wcr[14], all_ctrls);
        case 14:
-               __asm__ volatile("msr DBGWVR13_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[13]));
-               __asm__ volatile("msr DBGWCR13_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[13]));
+               SET_DBGWVRn(13, (uint64_t)debug_state->uds.ds32.wvr[13]);
+               SET_DBGWCRn(13, (uint64_t)debug_state->uds.ds32.wcr[13], all_ctrls);
        case 13:
-               __asm__ volatile("msr DBGWVR12_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[12]));
-               __asm__ volatile("msr DBGWCR12_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[12]));
+               SET_DBGWVRn(12, (uint64_t)debug_state->uds.ds32.wvr[12]);
+               SET_DBGWCRn(12, (uint64_t)debug_state->uds.ds32.wcr[12], all_ctrls);
        case 12:
-               __asm__ volatile("msr DBGWVR11_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[11]));
-               __asm__ volatile("msr DBGWCR11_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[11]));
+               SET_DBGWVRn(11, (uint64_t)debug_state->uds.ds32.wvr[11]);
+               SET_DBGWCRn(11, (uint64_t)debug_state->uds.ds32.wcr[11], all_ctrls);
        case 11:
-               __asm__ volatile("msr DBGWVR10_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[10]));
-               __asm__ volatile("msr DBGWCR10_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[10]));
+               SET_DBGWVRn(10, (uint64_t)debug_state->uds.ds32.wvr[10]);
+               SET_DBGWCRn(10, (uint64_t)debug_state->uds.ds32.wcr[10], all_ctrls);
        case 10:
-               __asm__ volatile("msr DBGWVR9_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[9]));
-               __asm__ volatile("msr DBGWCR9_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[9]));
+               SET_DBGWVRn(9, (uint64_t)debug_state->uds.ds32.wvr[9]);
+               SET_DBGWCRn(9, (uint64_t)debug_state->uds.ds32.wcr[9], all_ctrls);
        case 9:
-               __asm__ volatile("msr DBGWVR8_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[8]));
-               __asm__ volatile("msr DBGWCR8_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[8]));
+               SET_DBGWVRn(8, (uint64_t)debug_state->uds.ds32.wvr[8]);
+               SET_DBGWCRn(8, (uint64_t)debug_state->uds.ds32.wcr[8], all_ctrls);
        case 8:
-               __asm__ volatile("msr DBGWVR7_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[7]));
-               __asm__ volatile("msr DBGWCR7_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[7]));
+               SET_DBGWVRn(7, (uint64_t)debug_state->uds.ds32.wvr[7]);
+               SET_DBGWCRn(7, (uint64_t)debug_state->uds.ds32.wcr[7], all_ctrls);
        case 7:
-               __asm__ volatile("msr DBGWVR6_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[6]));
-               __asm__ volatile("msr DBGWCR6_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[6]));
+               SET_DBGWVRn(6, (uint64_t)debug_state->uds.ds32.wvr[6]);
+               SET_DBGWCRn(6, (uint64_t)debug_state->uds.ds32.wcr[6], all_ctrls);
        case 6:
-               __asm__ volatile("msr DBGWVR5_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[5]));
-               __asm__ volatile("msr DBGWCR5_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[5]));
+               SET_DBGWVRn(5, (uint64_t)debug_state->uds.ds32.wvr[5]);
+               SET_DBGWCRn(5, (uint64_t)debug_state->uds.ds32.wcr[5], all_ctrls);
        case 5:
-               __asm__ volatile("msr DBGWVR4_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[4]));
-               __asm__ volatile("msr DBGWCR4_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[4]));
+               SET_DBGWVRn(4, (uint64_t)debug_state->uds.ds32.wvr[4]);
+               SET_DBGWCRn(4, (uint64_t)debug_state->uds.ds32.wcr[4], all_ctrls);
        case 4:
-               __asm__ volatile("msr DBGWVR3_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[3]));
-               __asm__ volatile("msr DBGWCR3_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[3]));
+               SET_DBGWVRn(3, (uint64_t)debug_state->uds.ds32.wvr[3]);
+               SET_DBGWCRn(3, (uint64_t)debug_state->uds.ds32.wcr[3], all_ctrls);
        case 3:
-               __asm__ volatile("msr DBGWVR2_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[2]));
-               __asm__ volatile("msr DBGWCR2_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[2]));
+               SET_DBGWVRn(2, (uint64_t)debug_state->uds.ds32.wvr[2]);
+               SET_DBGWCRn(2, (uint64_t)debug_state->uds.ds32.wcr[2], all_ctrls);
        case 2:
-               __asm__ volatile("msr DBGWVR1_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[1]));
-               __asm__ volatile("msr DBGWCR1_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[1]));
+               SET_DBGWVRn(1, (uint64_t)debug_state->uds.ds32.wvr[1]);
+               SET_DBGWCRn(1, (uint64_t)debug_state->uds.ds32.wcr[1], all_ctrls);
        case 1:
-               __asm__ volatile("msr DBGWVR0_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wvr[0]));
-               __asm__ volatile("msr DBGWCR0_EL1, %0" : : "r"((uint64_t)debug_state->uds.ds32.wcr[0]));
+               SET_DBGWVRn(0, (uint64_t)debug_state->uds.ds32.wvr[0]);
+               SET_DBGWCRn(0, (uint64_t)debug_state->uds.ds32.wcr[0], all_ctrls);
        default:
                break;
        }
 
+#if defined(CONFIG_KERNEL_INTEGRITY)
+       if ((all_ctrls & (ARM_DBG_CR_MODE_CONTROL_PRIVILEGED | ARM_DBG_CR_HIGHER_MODE_ENABLE)) != 0) {
+               panic("sorry, self-hosted debug is not supported: 0x%llx", all_ctrls);
+       }
+#endif
+
        for (i = 0; i < debug_info->num_breakpoint_pairs; i++) {
                if (0 != debug_state->uds.ds32.bcr[i]) {
                        set_mde = 1;
@@ -511,36 +572,23 @@ void arm_debug_set32(arm_debug_state_t *debug_state)
         * Breakpoint/Watchpoint Enable
         */
        if (set_mde) {
-
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state |= 0x8000; // MDSCR_EL1[MDE]
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
-
+               update_mdscr(0, 0x8000); // MDSCR_EL1[MDE]
        } else {
-
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state &= ~0x8000;
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
-
+               update_mdscr(0x8000, 0);
        }
                
        /*
         * Software debug single step enable
         */
        if (debug_state->uds.ds32.mdscr_el1 & 0x1) {
-
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state = (state & ~0x8000) | 0x1; // ~MDE | SS : no brk/watch while single stepping (which we've set)
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
+               update_mdscr(0x8000, 1); // ~MDE | SS : no brk/watch while single stepping (which we've set)
 
                set_saved_state_cpsr((current_thread()->machine.upcb), 
                        get_saved_state_cpsr((current_thread()->machine.upcb)) | PSR64_SS);
 
        } else {
 
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state &= ~0x1;
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
+               update_mdscr(0x1, 0);
 
 #if SINGLE_STEP_RETIRE_ERRATA
                // Workaround for radar 20619637
@@ -557,10 +605,10 @@ void arm_debug_set64(arm_debug_state_t *debug_state)
 {
        struct cpu_data         *cpu_data_ptr;
        arm_debug_info_t        *debug_info = arm_debug_info();
-       volatile uint64_t       state;
        boolean_t               intr, set_mde = 0;
        arm_debug_state_t       off_state;
        uint32_t                        i;
+       uint64_t                        all_ctrls = 0;
 
        intr = ml_set_interrupts_enabled(FALSE);
        cpu_data_ptr = getCpuDatap();
@@ -575,110 +623,116 @@ void arm_debug_set64(arm_debug_state_t *debug_state)
 
        switch (debug_info->num_breakpoint_pairs) {
        case 16:
-               __asm__ volatile("msr DBGBVR15_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[15]));
-               __asm__ volatile("msr DBGBCR15_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[15]));
+               SET_DBGBVRn(15, debug_state->uds.ds64.bvr[15]);
+               SET_DBGBCRn(15, (uint64_t)debug_state->uds.ds64.bcr[15], all_ctrls);
        case 15:
-               __asm__ volatile("msr DBGBVR14_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[14]));
-               __asm__ volatile("msr DBGBCR14_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[14]));
+               SET_DBGBVRn(14, debug_state->uds.ds64.bvr[14]);
+               SET_DBGBCRn(14, (uint64_t)debug_state->uds.ds64.bcr[14], all_ctrls);
        case 14:
-               __asm__ volatile("msr DBGBVR13_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[13]));
-               __asm__ volatile("msr DBGBCR13_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[13]));
+               SET_DBGBVRn(13, debug_state->uds.ds64.bvr[13]);
+               SET_DBGBCRn(13, (uint64_t)debug_state->uds.ds64.bcr[13], all_ctrls);
        case 13:
-               __asm__ volatile("msr DBGBVR12_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[12]));
-               __asm__ volatile("msr DBGBCR12_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[12]));
+               SET_DBGBVRn(12, debug_state->uds.ds64.bvr[12]);
+               SET_DBGBCRn(12, (uint64_t)debug_state->uds.ds64.bcr[12], all_ctrls);
        case 12:
-               __asm__ volatile("msr DBGBVR11_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[11]));
-               __asm__ volatile("msr DBGBCR11_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[11]));
+               SET_DBGBVRn(11, debug_state->uds.ds64.bvr[11]);
+               SET_DBGBCRn(11, (uint64_t)debug_state->uds.ds64.bcr[11], all_ctrls);
        case 11:
-               __asm__ volatile("msr DBGBVR10_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[10]));
-               __asm__ volatile("msr DBGBCR10_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[10]));
+               SET_DBGBVRn(10, debug_state->uds.ds64.bvr[10]);
+               SET_DBGBCRn(10, (uint64_t)debug_state->uds.ds64.bcr[10], all_ctrls);
        case 10:
-               __asm__ volatile("msr DBGBVR9_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[9]));
-               __asm__ volatile("msr DBGBCR9_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[9]));
+               SET_DBGBVRn(9, debug_state->uds.ds64.bvr[9]);
+               SET_DBGBCRn(9, (uint64_t)debug_state->uds.ds64.bcr[9], all_ctrls);
        case 9:
-               __asm__ volatile("msr DBGBVR8_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[8]));
-               __asm__ volatile("msr DBGBCR8_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[8]));
+               SET_DBGBVRn(8, debug_state->uds.ds64.bvr[8]);
+               SET_DBGBCRn(8, (uint64_t)debug_state->uds.ds64.bcr[8], all_ctrls);
        case 8:
-               __asm__ volatile("msr DBGBVR7_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[7]));
-               __asm__ volatile("msr DBGBCR7_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[7]));
+               SET_DBGBVRn(7, debug_state->uds.ds64.bvr[7]);
+               SET_DBGBCRn(7, (uint64_t)debug_state->uds.ds64.bcr[7], all_ctrls);
        case 7:
-               __asm__ volatile("msr DBGBVR6_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[6]));
-               __asm__ volatile("msr DBGBCR6_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[6]));
+               SET_DBGBVRn(6, debug_state->uds.ds64.bvr[6]);
+               SET_DBGBCRn(6, (uint64_t)debug_state->uds.ds64.bcr[6], all_ctrls);
        case 6:
-               __asm__ volatile("msr DBGBVR5_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[5]));
-               __asm__ volatile("msr DBGBCR5_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[5]));
+               SET_DBGBVRn(5, debug_state->uds.ds64.bvr[5]);
+               SET_DBGBCRn(5, (uint64_t)debug_state->uds.ds64.bcr[5], all_ctrls);
        case 5:
-               __asm__ volatile("msr DBGBVR4_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[4]));
-               __asm__ volatile("msr DBGBCR4_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[4]));
+               SET_DBGBVRn(4, debug_state->uds.ds64.bvr[4]);
+               SET_DBGBCRn(4, (uint64_t)debug_state->uds.ds64.bcr[4], all_ctrls);
        case 4:
-               __asm__ volatile("msr DBGBVR3_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[3]));
-               __asm__ volatile("msr DBGBCR3_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[3]));
+               SET_DBGBVRn(3, debug_state->uds.ds64.bvr[3]);
+               SET_DBGBCRn(3, (uint64_t)debug_state->uds.ds64.bcr[3], all_ctrls);
        case 3:
-               __asm__ volatile("msr DBGBVR2_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[2]));
-               __asm__ volatile("msr DBGBCR2_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[2]));
+               SET_DBGBVRn(2, debug_state->uds.ds64.bvr[2]);
+               SET_DBGBCRn(2, (uint64_t)debug_state->uds.ds64.bcr[2], all_ctrls);
        case 2:
-               __asm__ volatile("msr DBGBVR1_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[1]));
-               __asm__ volatile("msr DBGBCR1_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[1]));
+               SET_DBGBVRn(1, debug_state->uds.ds64.bvr[1]);
+               SET_DBGBCRn(1, (uint64_t)debug_state->uds.ds64.bcr[1], all_ctrls);
        case 1:
-               __asm__ volatile("msr DBGBVR0_EL1, %0" : : "r"(debug_state->uds.ds64.bvr[0]));
-               __asm__ volatile("msr DBGBCR0_EL1, %0" : : "r"(debug_state->uds.ds64.bcr[0]));
+               SET_DBGBVRn(0, debug_state->uds.ds64.bvr[0]);
+               SET_DBGBCRn(0, (uint64_t)debug_state->uds.ds64.bcr[0], all_ctrls);
        default:
                break;
        }
 
        switch (debug_info->num_watchpoint_pairs) {
        case 16:
-               __asm__ volatile("msr DBGWVR15_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[15]));
-               __asm__ volatile("msr DBGWCR15_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[15]));
+               SET_DBGWVRn(15, debug_state->uds.ds64.wvr[15]);
+               SET_DBGWCRn(15, (uint64_t)debug_state->uds.ds64.wcr[15], all_ctrls);
        case 15:
-               __asm__ volatile("msr DBGWVR14_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[14]));
-               __asm__ volatile("msr DBGWCR14_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[14]));
+               SET_DBGWVRn(14, debug_state->uds.ds64.wvr[14]);
+               SET_DBGWCRn(14, (uint64_t)debug_state->uds.ds64.wcr[14], all_ctrls);
        case 14:
-               __asm__ volatile("msr DBGWVR13_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[13]));
-               __asm__ volatile("msr DBGWCR13_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[13]));
+               SET_DBGWVRn(13, debug_state->uds.ds64.wvr[13]);
+               SET_DBGWCRn(13, (uint64_t)debug_state->uds.ds64.wcr[13], all_ctrls);
        case 13:
-               __asm__ volatile("msr DBGWVR12_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[12]));
-               __asm__ volatile("msr DBGWCR12_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[12]));
+               SET_DBGWVRn(12, debug_state->uds.ds64.wvr[12]);
+               SET_DBGWCRn(12, (uint64_t)debug_state->uds.ds64.wcr[12], all_ctrls);
        case 12:
-               __asm__ volatile("msr DBGWVR11_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[11]));
-               __asm__ volatile("msr DBGWCR11_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[11]));
+               SET_DBGWVRn(11, debug_state->uds.ds64.wvr[11]);
+               SET_DBGWCRn(11, (uint64_t)debug_state->uds.ds64.wcr[11], all_ctrls);
        case 11:
-               __asm__ volatile("msr DBGWVR10_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[10]));
-               __asm__ volatile("msr DBGWCR10_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[10]));
+               SET_DBGWVRn(10, debug_state->uds.ds64.wvr[10]);
+               SET_DBGWCRn(10, (uint64_t)debug_state->uds.ds64.wcr[10], all_ctrls);
        case 10:
-               __asm__ volatile("msr DBGWVR9_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[9]));
-               __asm__ volatile("msr DBGWCR9_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[9]));
+               SET_DBGWVRn(9, debug_state->uds.ds64.wvr[9]);
+               SET_DBGWCRn(9, (uint64_t)debug_state->uds.ds64.wcr[9], all_ctrls);
        case 9:
-               __asm__ volatile("msr DBGWVR8_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[8]));
-               __asm__ volatile("msr DBGWCR8_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[8]));
+               SET_DBGWVRn(8, debug_state->uds.ds64.wvr[8]);
+               SET_DBGWCRn(8, (uint64_t)debug_state->uds.ds64.wcr[8], all_ctrls);
        case 8:
-               __asm__ volatile("msr DBGWVR7_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[7]));
-               __asm__ volatile("msr DBGWCR7_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[7]));
+               SET_DBGWVRn(7, debug_state->uds.ds64.wvr[7]);
+               SET_DBGWCRn(7, (uint64_t)debug_state->uds.ds64.wcr[7], all_ctrls);
        case 7:
-               __asm__ volatile("msr DBGWVR6_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[6]));
-               __asm__ volatile("msr DBGWCR6_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[6]));
+               SET_DBGWVRn(6, debug_state->uds.ds64.wvr[6]);
+               SET_DBGWCRn(6, (uint64_t)debug_state->uds.ds64.wcr[6], all_ctrls);
        case 6:
-               __asm__ volatile("msr DBGWVR5_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[5]));
-               __asm__ volatile("msr DBGWCR5_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[5]));
+               SET_DBGWVRn(5, debug_state->uds.ds64.wvr[5]);
+               SET_DBGWCRn(5, (uint64_t)debug_state->uds.ds64.wcr[5], all_ctrls);
        case 5:
-               __asm__ volatile("msr DBGWVR4_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[4]));
-               __asm__ volatile("msr DBGWCR4_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[4]));
+               SET_DBGWVRn(4, debug_state->uds.ds64.wvr[4]);
+               SET_DBGWCRn(4, (uint64_t)debug_state->uds.ds64.wcr[4], all_ctrls);
        case 4:
-               __asm__ volatile("msr DBGWVR3_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[3]));
-               __asm__ volatile("msr DBGWCR3_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[3]));
+               SET_DBGWVRn(3, debug_state->uds.ds64.wvr[3]);
+               SET_DBGWCRn(3, (uint64_t)debug_state->uds.ds64.wcr[3], all_ctrls);
        case 3:
-               __asm__ volatile("msr DBGWVR2_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[2]));
-               __asm__ volatile("msr DBGWCR2_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[2]));
+               SET_DBGWVRn(2, debug_state->uds.ds64.wvr[2]);
+               SET_DBGWCRn(2, (uint64_t)debug_state->uds.ds64.wcr[2], all_ctrls);
        case 2:
-               __asm__ volatile("msr DBGWVR1_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[1]));
-               __asm__ volatile("msr DBGWCR1_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[1]));
+               SET_DBGWVRn(1, debug_state->uds.ds64.wvr[1]);
+               SET_DBGWCRn(1, (uint64_t)debug_state->uds.ds64.wcr[1], all_ctrls);
        case 1:
-               __asm__ volatile("msr DBGWVR0_EL1, %0" : : "r"(debug_state->uds.ds64.wvr[0]));
-               __asm__ volatile("msr DBGWCR0_EL1, %0" : : "r"(debug_state->uds.ds64.wcr[0]));
+               SET_DBGWVRn(0, debug_state->uds.ds64.wvr[0]);
+               SET_DBGWCRn(0, (uint64_t)debug_state->uds.ds64.wcr[0], all_ctrls);
        default:
                break;
        }
 
+#if defined(CONFIG_KERNEL_INTEGRITY)
+       if ((all_ctrls & (ARM_DBG_CR_MODE_CONTROL_PRIVILEGED | ARM_DBG_CR_HIGHER_MODE_ENABLE)) != 0) {
+               panic("sorry, self-hosted debug is not supported: 0x%llx", all_ctrls);
+       }
+#endif
+
        for (i = 0; i < debug_info->num_breakpoint_pairs; i++) {
                if (0 != debug_state->uds.ds64.bcr[i]) {
                        set_mde = 1;
@@ -697,11 +751,7 @@ void arm_debug_set64(arm_debug_state_t *debug_state)
         * Breakpoint/Watchpoint Enable
         */
        if (set_mde) {
-
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state |= 0x8000; // MDSCR_EL1[MDE]
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
-
+               update_mdscr(0, 0x8000); // MDSCR_EL1[MDE]
        }
                
        /*
@@ -709,18 +759,14 @@ void arm_debug_set64(arm_debug_state_t *debug_state)
         */
        if (debug_state->uds.ds64.mdscr_el1 & 0x1) {
 
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state = (state & ~0x8000) | 0x1; // ~MDE | SS : no brk/watch while single stepping (which we've set)
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
+               update_mdscr(0x8000, 1); // ~MDE | SS : no brk/watch while single stepping (which we've set)
 
                set_saved_state_cpsr((current_thread()->machine.upcb), 
                        get_saved_state_cpsr((current_thread()->machine.upcb)) | PSR64_SS);
 
        } else {
 
-               __asm__ volatile("mrs %0, MDSCR_EL1" : "=r"(state));
-               state &= ~0x1;
-               __asm__ volatile("msr MDSCR_EL1, %0" : : "r"(state));
+               update_mdscr(0x1, 0);
 
 #if SINGLE_STEP_RETIRE_ERRATA
                // Workaround for radar 20619637
index d5391b3279a757fb2ab62d123c45c87ec1151a93..61b62741930dd155a7050eae1336a91b86fccf47 100644 (file)
@@ -425,6 +425,7 @@ static kern_return_t
 lt_test_trylocks()
 {
        boolean_t success; 
+       extern unsigned int real_ncpus;
        
        /* 
         * First mtx try lock succeeds, second fails.
@@ -512,9 +513,15 @@ lt_test_trylocks()
        lt_start_trylock_thread(lt_trylock_hw_lock_with_to);
        success = hw_lock_to(&lt_hw_lock, 100);
        T_ASSERT_NOTNULL(success, "First spin lock with timeout should succeed");
+       if (real_ncpus == 1) {
+               mp_enable_preemption(); /* if we re-enable preemption, the other thread can timeout and exit */
+       }
        OSIncrementAtomic((volatile SInt32*)&lt_thread_lock_grabbed);
        lt_wait_for_lock_test_threads();
        T_ASSERT_NULL(lt_thread_lock_success, "Second spin lock with timeout should fail and timeout");
+       if (real_ncpus == 1) {
+               mp_disable_preemption(); /* don't double-enable when we unlock */
+       }
        hw_lock_unlock(&lt_hw_lock);
 
        lt_reset();
@@ -524,9 +531,15 @@ lt_test_trylocks()
        OSMemoryBarrier();
        lt_start_trylock_thread(lt_trylock_hw_lock_with_to);
        hw_lock_lock(&lt_hw_lock);
+       if (real_ncpus == 1) {
+               mp_enable_preemption(); /* if we re-enable preemption, the other thread can timeout and exit */
+       }
        OSIncrementAtomic((volatile SInt32*)&lt_thread_lock_grabbed);
        lt_wait_for_lock_test_threads();
        T_ASSERT_NULL(lt_thread_lock_success, "after taking a spin lock, lock attempt with timeout should fail");
+       if (real_ncpus == 1) {
+               mp_disable_preemption(); /* don't double-enable when we unlock */
+       }
        hw_lock_unlock(&lt_hw_lock);
 
        success = lck_spin_try_lock(&lt_lck_spin_t);
@@ -541,9 +554,15 @@ lt_test_trylocks()
        lt_target_done_threads = 1;
        lt_start_trylock_thread(lt_trylock_spin_try_lock);
        lck_spin_lock(&lt_lck_spin_t);
+       if (real_ncpus == 1) {
+               mp_enable_preemption(); /* if we re-enable preemption, the other thread can timeout and exit */
+       }
        OSIncrementAtomic((volatile SInt32*)&lt_thread_lock_grabbed);
        lt_wait_for_lock_test_threads();
        T_ASSERT_NULL(lt_thread_lock_success, "spin trylock attempt of previously held lock should fail");
+       if (real_ncpus == 1) {
+               mp_disable_preemption(); /* don't double-enable when we unlock */
+       }
        lck_spin_unlock(&lt_lck_spin_t);
 
        return KERN_SUCCESS;
index ce62e62bd616deda253e40d84c5549df13f339bc..a6971fa74cd986df586f49cb914c0c33009b9993 100644 (file)
  *     Aff1    Cluster ID
  *     Aff0    CPU ID
  */
-#define MPIDR_PNE_SHIFT                                16      // pcore not ecore
-#define MPIDR_PNE                                              (1 << MPIDR_PNE_SHIFT)
 #define MPIDR_AFF0_MASK                                0xFF
 #define MPIDR_AFF1_MASK                                0xFF00
 #define MPIDR_AFF2_MASK                                0xFF0000
index 6e65c759849552df208944cae939f587f1761891..cf022d32fcfe48bf0793de87a2f626194f05f7fa 100644 (file)
@@ -154,8 +154,6 @@ unix_syscall(struct arm_saved_state * regs, thread_t thread_act,
 extern void
 mach_syscall(struct arm_saved_state*);
 
-volatile perfCallback    perfTrapHook = NULL;  /* Pointer to CHUD trap hook routine */
-
 #if CONFIG_DTRACE
 extern kern_return_t dtrace_user_probe(arm_saved_state_t* regs);
 extern boolean_t dtrace_tally_fault(user_addr_t);
@@ -498,7 +496,7 @@ sleh_synchronous(arm_context_t *context, uint32_t esr, vm_offset_t far)
                break;
 
        case ESR_EC_BKPT_REG_MATCH_EL1:
-               if (FSC_DEBUG_FAULT == ISS_SSDE_FSC(esr)) {
+               if (!PE_i_can_has_debugger(NULL) && FSC_DEBUG_FAULT == ISS_SSDE_FSC(esr)) {
                        kprintf("Hardware Breakpoint Debug exception from kernel.  Hanging here (by design).\n");
                        for (;;);
 
@@ -523,7 +521,7 @@ sleh_synchronous(arm_context_t *context, uint32_t esr, vm_offset_t far)
                break;
 
        case ESR_EC_SW_STEP_DEBUG_EL1:
-               if (FSC_DEBUG_FAULT == ISS_SSDE_FSC(esr)) {
+               if (!PE_i_can_has_debugger(NULL) && FSC_DEBUG_FAULT == ISS_SSDE_FSC(esr)) {
                        kprintf("Software Step Debug exception from kernel.  Hanging here (by design).\n");
                        for (;;);
 
index ad181f7056bb549016c1c5a67330251cd3a1f9a5..24a6dba7f79269bb7cd6cab7e9ad3a59d7e48b71 100644 (file)
@@ -713,16 +713,25 @@ common_start:
        mov             x0, #0
        msr             TPIDR_EL1, x0                                           // Set thread register
 
+#if defined(APPLE_ARM64_ARCH_FAMILY)
+       // Initialization common to all Apple targets
+       ARM64_IS_PCORE x15
+       ARM64_READ_EP_SPR x15, x12, ARM64_REG_EHID4, ARM64_REG_HID4
+       orr             x12, x12, ARM64_REG_HID4_DisDcMVAOps
+       orr             x12, x12, ARM64_REG_HID4_DisDcSWL2Ops
+       ARM64_WRITE_EP_SPR x15, x12, ARM64_REG_EHID4, ARM64_REG_HID4
+#endif  // APPLE_ARM64_ARCH_FAMILY
+
 #if defined(APPLECYCLONE) || defined(APPLETYPHOON)
        //
        // Cyclone/Typhoon-Specific initialization
-       // For tunable summary, see <rdar://problem/13503621> Alcatraz/H6: Confirm Cyclone CPU tunables have been set
+       // For tunable summary, see <rdar://problem/13503621>
        //
 
        //
        // Disable LSP flush with context switch to work around bug in LSP
        // that can cause Cyclone to wedge when CONTEXTIDR is written.
-       // <rdar://problem/12387704> Innsbruck11A175: panic(cpu 0 caller 0xffffff800024e30c): "wait queue deadlock - wq=0xffffff805a7a63c0, cpu=0\n"
+       // <rdar://problem/12387704>
        //
 
        mrs             x12, ARM64_REG_HID0
@@ -740,15 +749,6 @@ common_start:
        orr             x12, x12, ARM64_REG_HID3_DisXmonSnpEvictTriggerL2StarvationMode
        msr             ARM64_REG_HID3, x12
 
-       // Do not disable cache ops -- XNU's cache operations already are no-op'ed for Cyclone, but explicit _Force variants are provided
-       // for when we really do need the L2 cache to be cleaned: <rdar://problem/14350417> Innsbruck11A416: Panic logs not preserved on h6
-/*
-       mrs             x12, ARM64_REG_HID4
-       orr             x12, x12, ARM64_REG_HID4_DisDcMVAOps
-       orr             x12, x12, ARM64_REG_HID4_DisDcSWL2Ops
-       msr             ARM64_REG_HID4, x12
-*/
-
        mrs             x12, ARM64_REG_HID5
        and             x12, x12, (~ARM64_REG_HID5_DisHwpLd)
        and             x12, x12, (~ARM64_REG_HID5_DisHwpSt)
@@ -765,20 +765,37 @@ common_start:
 #endif // APPLECYCLONE || APPLETYPHOON
 
 #if defined(APPLETWISTER)
-       mrs     x12, ARM64_REG_HID11
-       and     x12, x12, (~ARM64_REG_HID11_DisFillC1BubOpt)
-       msr     ARM64_REG_HID11, x12
+
+       // rdar://problem/36112905: Set CYC_CFG:skipInit to pull in isAlive by one DCLK
+       // to work around potential hang.  Must only be applied to Maui C0.
+       mrs             x12, MIDR_EL1
+       ubfx            x13, x12, #MIDR_EL1_PNUM_SHIFT, #12
+       cmp             x13, #4         // Part number 4 => Maui, 5 => Malta/Elba
+       bne             Lskip_isalive
+       ubfx            x13, x12, #MIDR_EL1_VAR_SHIFT, #4
+       cmp             x13, #2         // variant 2 => Maui C0
+       b.lt            Lskip_isalive
+
+       mrs             x12, ARM64_REG_CYC_CFG
+       orr             x12, x12, ARM64_REG_CYC_CFG_skipInit
+       msr             ARM64_REG_CYC_CFG, x12
+
+Lskip_isalive:
+
+       mrs             x12, ARM64_REG_HID11
+       and             x12, x12, (~ARM64_REG_HID11_DisFillC1BubOpt)
+       msr             ARM64_REG_HID11, x12
 
        // Change the default memcache data set ID from 0 to 15 for all agents
        mrs             x12, ARM64_REG_HID8
        orr             x12, x12, (ARM64_REG_HID8_DataSetID0_VALUE | ARM64_REG_HID8_DataSetID1_VALUE)
-       orr     x12, x12, (ARM64_REG_HID8_DataSetID2_VALUE | ARM64_REG_HID8_DataSetID3_VALUE)
+       orr             x12, x12, (ARM64_REG_HID8_DataSetID2_VALUE | ARM64_REG_HID8_DataSetID3_VALUE)
        msr             ARM64_REG_HID8, x12
 
        // Use 4-cycle MUL latency to avoid denormal stalls
-       mrs     x12, ARM64_REG_HID7
-       orr     x12, x12, #ARM64_REG_HID7_disNexFastFmul
-       msr     ARM64_REG_HID7, x12
+       mrs             x12, ARM64_REG_HID7
+       orr             x12, x12, #ARM64_REG_HID7_disNexFastFmul
+       msr             ARM64_REG_HID7, x12
 
        // disable reporting of TLB-multi-hit-error
        // <rdar://problem/22163216> 
@@ -814,7 +831,6 @@ common_start:
 #if defined(ARM64_BOARD_CONFIG_T8011)
        // Clear DisDcZvaCmdOnly 
        // Per Myst A0/B0 tunables document
-       // https://seg-docs.csg.apple.com/projects/myst//release/UserManual/tunables_a0/ACC.html
        // <rdar://problem/27627428> Myst: Confirm ACC Per-CPU Tunables
        mrs             x12, ARM64_REG_HID3
        and             x12, x12, ~ARM64_REG_HID3_DisDcZvaCmdOnly
index 0090356871997633f509ec15a5356b363d7c0a8a..fcf59e3d3ba88856fe70a599474e5bc79c8ce600 100644 (file)
@@ -725,11 +725,9 @@ atm_send_user_notification(
                return KERN_FAILURE;
        }
 
-       /* Set the honor queue limit option on the thread. */
-       th->options |= TH_OPT_HONOR_QLIMIT;
+       thread_set_honor_qlimit(th);
        kr = atm_collect_trace_info(user_port, aid, sub_aid, flags, buffers_array, count, sizes_array, count);
-       /* Make sure that honor queue limit option is unset on the thread. */
-       th->options &= (~TH_OPT_HONOR_QLIMIT);
+       thread_clear_honor_qlimit(th);
 
        if (kr != KERN_SUCCESS) {
                ipc_port_release_send(user_port);
@@ -793,11 +791,9 @@ atm_send_proc_inspect_notification(
                return KERN_FAILURE;
        }
 
-       /* Set the honor queue limit option on the thread. */
-       th->options |= TH_OPT_HONOR_QLIMIT;
+       thread_set_honor_qlimit(th);
        kr =  atm_inspect_process_buffer(user_port, traced_pid, traced_uniqueid, buffer_size, memory_port);
-       /* Make sure that honor queue limit option is unset on the thread. */
-       th->options &= (~TH_OPT_HONOR_QLIMIT);
+       thread_clear_honor_qlimit(th);
 
        if (kr != KERN_SUCCESS) {
                ipc_port_release_send(user_port);
diff --git a/osfmk/chud/chud_cpu.c b/osfmk/chud/chud_cpu.c
deleted file mode 100644 (file)
index c21a40e..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#include <mach/mach_types.h>
-#include <mach/mach_host.h>
-
-#include <kern/host.h>
-#include <kern/processor.h>
-#include <kern/cpu_data.h>
-#include <kern/machine.h>
-#include <machine/machine_routines.h>
-
-#include <chud/chud_xnu.h>
-
-#if 0
-#pragma mark **** cpu count ****
-#endif
-
-__private_extern__ int 
-chudxnu_logical_cpu_count(void)
-{
-       return machine_info.logical_cpu_max;
-}
-
-__private_extern__ int
-chudxnu_phys_cpu_count(void)
-{
-    host_basic_info_data_t hinfo;
-    kern_return_t kr;
-    mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
-
-    kr = host_info(host_self(), HOST_BASIC_INFO, (integer_t *)&hinfo, &count);
-    if(kr == KERN_SUCCESS) {
-        return hinfo.max_cpus;
-    } else {
-        return 1;  // fall back to 1, 0 doesn't make sense at all
-    }
-}
-
-__private_extern__ int
-chudxnu_cpu_number(void)
-{
-    return cpu_number();
-}
-
-#if 0
-#pragma mark **** interrupts enable/disable ****
-#endif
-
-__private_extern__ boolean_t
-chudxnu_set_interrupts_enabled(boolean_t enable)
-{
-    return ml_set_interrupts_enabled(enable);
-}
-
-__private_extern__ void
-chudxnu_cause_interrupt(void)
-{
-    ml_cause_interrupt();
-}
-
-#if 0
-#pragma mark **** preemption enable/disable ****
-#endif
-
-__private_extern__ void
-chudxnu_enable_preemption(void)
-{
-       enable_preemption();
-}
-
-__private_extern__ void
-chudxnu_disable_preemption(void)
-{
-       disable_preemption();
-}
-
-__private_extern__ int
-chudxnu_get_preemption_level(void)
-{
-       return get_preemption_level();
-}
-
diff --git a/osfmk/chud/chud_glue.c b/osfmk/chud/chud_glue.c
deleted file mode 100644 (file)
index a721a73..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-void *chudxnu_platform_ptr(void);
-
-void *
-chudxnu_platform_ptr(void)
-{
-       return (void *)0;
-}
-
-
diff --git a/osfmk/chud/chud_memory.c b/osfmk/chud/chud_memory.c
deleted file mode 100644 (file)
index 21209b0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <mach/vm_param.h>
-#include <chud/chud_xnu.h>
-#include <machine/machine_routines.h>
-
-extern unsigned int IODefaultCacheBits(addr64_t pa);
-extern unsigned int vm_page_free_count;
-extern unsigned int vm_page_inactive_count;
-
-__private_extern__ uint64_t 
-chudxnu_avail_memory_size(void)
-{
-    return max_mem;
-}
-
-__private_extern__ uint64_t 
-chudxnu_phys_memory_size(void)
-{
-    return mem_actual;
-}
-
-/* 
- * This function is not intended to be valid for any amount of time,
- * it is just an instantaneous snapshot of the current free memory size.
- */
-__private_extern__
-uint64_t chudxnu_free_memory_size(void)
-{
-    return (uint64_t)vm_page_free_count * (uint64_t)page_size;
-}
-
-/*
- * This function is not intended to be valid for any amount of time,
- * it is just an instantaneous snapshot of the current inactive memory size.
- */
-__private_extern__
-uint64_t chudxnu_inactive_memory_size(void)
-{
-       return (uint64_t)vm_page_inactive_count * (uint64_t)page_size;
-}
-
diff --git a/osfmk/chud/chud_osfmk_callback.c b/osfmk/chud/chud_osfmk_callback.c
deleted file mode 100644 (file)
index 98e1fce..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <stdint.h>
-#include <mach/boolean.h>
-#include <mach/mach_types.h>
-
-#include <kern/kern_types.h>
-#include <kern/processor.h>
-#include <kern/timer_call.h>
-#include <kern/thread_call.h>
-#include <kern/kalloc.h>
-#include <kern/thread.h>
-
-#include <libkern/OSAtomic.h>
-
-#include <machine/machine_routines.h>
-#include <machine/cpu_data.h>
-
-#include <chud/chud_xnu.h>
-#include <chud/chud_xnu_private.h>
-
-#if 0
-#pragma mark **** timer ****
-#endif
-
-__private_extern__ chud_timer_t
-chudxnu_timer_alloc(chudxnu_timer_callback_func_t func, thread_call_param_t param0)
-{
-    return (chud_timer_t)thread_call_allocate((thread_call_func_t)func, param0);
-}
-
-__private_extern__ kern_return_t
-chudxnu_timer_callback_enter(
-       chud_timer_t timer,
-       thread_call_param_t param1,
-       uint32_t time,
-       uint32_t units)
-{
-    uint64_t t_delay;
-    clock_interval_to_deadline(time, units, &t_delay);
-    thread_call_enter1_delayed((thread_call_t)timer, param1, t_delay);
-    return KERN_SUCCESS;
-}
-
-__private_extern__ kern_return_t
-chudxnu_timer_callback_cancel(chud_timer_t timer)
-{
-    thread_call_cancel((thread_call_t)timer);
-    return KERN_SUCCESS;
-}
-
-__private_extern__ kern_return_t
-chudxnu_timer_free(chud_timer_t timer)
-{
-    thread_call_cancel((thread_call_t)timer);
-    thread_call_free((thread_call_t)timer);
-    return KERN_SUCCESS;
-}
-
-
diff --git a/osfmk/chud/chud_thread.c b/osfmk/chud/chud_thread.c
deleted file mode 100644 (file)
index 2b804af..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2003-2009 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <mach/mach_types.h>
-#include <mach/task.h>
-#include <mach/thread_act.h>
-
-#include <kern/kern_types.h>
-#include <kern/processor.h>
-#include <kern/thread.h>
-#include <kern/kalloc.h>
-
-#include <chud/chud_xnu.h>
-#include <chud/chud_xnu_private.h>
-#include <chud/chud_thread.h>
-
-#include <machine/machine_routines.h>
-
-#include <libkern/OSAtomic.h>
-
-#if KPC
-#include <kern/kpc.h>
-#endif
-
-#if KPERF
-#include <kperf/kperf.h>
-#endif
-
-// include the correct file to find real_ncpus
-#if defined(__i386__) || defined(__x86_64__)
-#      include <i386/mp.h>     
-#elif defined(__arm__) || defined (__arm64__)
-#      include <arm/cpu_internal.h>
-#else
-// fall back on declaring it extern.  The linker will sort us out.
-extern unsigned int real_ncpus;
-#endif
-
-// Mask for supported options
-#define T_CHUD_BIND_OPT_MASK (-1UL)
-
-#if 0
-#pragma mark **** thread binding ****
-#endif
-
-/*
- * This method will bind a given thread to the requested CPU starting at the
- * next time quantum.  If the thread is the current thread, this method will
- * force a thread_block().  The result is that if you call this method on the
- * current thread, you will be on the requested CPU when this method returns.
- */
-__private_extern__ kern_return_t
-chudxnu_bind_thread(thread_t thread, int cpu, __unused int options)
-{
-    processor_t proc = NULL;
-
-       if(cpu < 0 || (unsigned int)cpu >= real_ncpus) // sanity check
-               return KERN_FAILURE;
-
-       // temporary restriction until after phase 2 of the scheduler
-       if(thread != current_thread())
-               return KERN_FAILURE; 
-       
-       proc = cpu_to_processor(cpu);
-
-       /* 
-        * Potentially racey, but mainly to prevent bind to shutdown
-        * processor.
-        */
-       if(proc && !(proc->state == PROCESSOR_OFF_LINE) &&
-                       !(proc->state == PROCESSOR_SHUTDOWN)) {
-               
-               thread_bind(proc);
-
-               /*
-                * If we're trying to bind the current thread, and
-                * we're not on the target cpu, and not at interrupt
-                * context, block the current thread to force a
-                * reschedule on the target CPU.
-                */
-               if(thread == current_thread() && 
-                       !ml_at_interrupt_context() && cpu_number() != cpu) {
-                       (void)thread_block(THREAD_CONTINUE_NULL);
-               }
-               return KERN_SUCCESS;
-       }
-    return KERN_FAILURE;
-}
-
-__private_extern__ kern_return_t
-chudxnu_unbind_thread(thread_t thread, __unused int options)
-{
-       if(thread == current_thread())
-               thread_bind(PROCESSOR_NULL);
-    return KERN_SUCCESS;
-}
diff --git a/osfmk/chud/chud_thread.h b/osfmk/chud/chud_thread.h
deleted file mode 100644 (file)
index 86976de..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2007-2009 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#ifndef _CHUD_THREAD_H_
-#define _CHUD_THREAD_H_
-
-
-#include <kern/thread.h>
-
-#endif /* _CHUD_THREAD_H_ */
diff --git a/osfmk/chud/chud_xnu.h b/osfmk/chud/chud_xnu.h
deleted file mode 100644 (file)
index 56c7e65..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2003-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#ifndef _CHUD_XNU_H_
-#define _CHUD_XNU_H_
-
-#include <stdint.h>
-#include <mach/boolean.h>
-#include <mach/mach_types.h>
-#include <kern/thread_call.h>
-
-/* Unslide the provided pointer if it's a kernel address. */
-static inline uint64_t
-chudxnu_vm_unslide( uint64_t ptr, int kaddr )
-{
-       if( !kaddr )
-               return ptr;
-
-       return VM_KERNEL_UNSLIDE(ptr);
-}
-
-#if 0
-#pragma mark **** version ****
-#endif
-extern uint32_t chudxnu_version(void);
-
-#if 0
-#pragma mark **** task ****
-#endif
-// ********************************************************************************
-// task
-// ********************************************************************************
-extern kern_return_t chudxnu_task_read(task_t task, void *kernaddr, uint64_t usraddr, vm_size_t size);
-extern kern_return_t chudxnu_task_write(task_t task, uint64_t useraddr, void *kernaddr, vm_size_t size);
-extern kern_return_t chudxnu_kern_read(void *destaddr, vm_offset_t srcaddr, vm_size_t size);
-extern kern_return_t chudxnu_kern_write(vm_offset_t destaddr, void *srcaddr, vm_size_t size);
-
-extern boolean_t chudxnu_is_64bit_task(task_t task);
-
-#if 0
-#pragma mark **** thread ****
-#endif
-// ********************************************************************************
-// thread
-// ********************************************************************************
-extern kern_return_t chudxnu_bind_thread(thread_t thread, int cpu, int options);
-extern kern_return_t chudxnu_unbind_thread(thread_t thread, int options);
-
-extern kern_return_t chudxnu_thread_get_state(thread_t thread, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t *count, boolean_t user_only);
-extern kern_return_t chudxnu_thread_set_state(thread_t thread, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t count, boolean_t user_only);
-
-extern kern_return_t chudxnu_thread_get_callstack64(thread_t thread, uint64_t *callStack, mach_msg_type_number_t *count, boolean_t user_only);
-extern kern_return_t chudxnu_thread_get_callstack64_kperf(thread_t thread, uint64_t *callStack, mach_msg_type_number_t *count, boolean_t user_only);
-
-#if 0
-#pragma mark **** memory ****
-#endif
-// ********************************************************************************
-// memory
-// ********************************************************************************
-
-extern uint64_t chudxnu_avail_memory_size(void);
-extern uint64_t chudxnu_phys_memory_size(void);
-extern uint64_t chudxnu_free_memory_size(void);
-extern uint64_t chudxnu_inactive_memory_size(void);
-
-#if 0
-#pragma mark **** cpu ****
-#endif
-// ********************************************************************************
-// cpu
-// ********************************************************************************
-extern int chudxnu_logical_cpu_count(void);
-extern int chudxnu_phys_cpu_count(void);
-extern int chudxnu_cpu_number(void);
-
-extern kern_return_t chudxnu_enable_cpu(int cpu, boolean_t enable);
-
-extern boolean_t chudxnu_set_interrupts_enabled(boolean_t enable);
-extern void chudxnu_cause_interrupt(void);
-
-extern void chudxnu_enable_preemption(void);
-extern void chudxnu_disable_preemption(void);
-extern int chudxnu_get_preemption_level(void);
-
-extern kern_return_t chudxnu_perfmon_acquire_facility(task_t);
-extern kern_return_t chudxnu_perfmon_release_facility(task_t);
-
-typedef struct {
-    uint32_t hwResets;
-    uint32_t hwMachineChecks;
-    uint32_t hwDSIs;
-    uint32_t hwISIs;
-    uint32_t hwExternals;
-    uint32_t hwAlignments;
-    uint32_t hwPrograms;
-    uint32_t hwFloatPointUnavailable;
-    uint32_t hwDecrementers;
-    uint32_t hwIOErrors;
-    uint32_t hwSystemCalls;
-    uint32_t hwTraces;
-    uint32_t hwFloatingPointAssists;
-    uint32_t hwPerformanceMonitors;
-    uint32_t hwAltivecs;
-    uint32_t hwInstBreakpoints;
-    uint32_t hwSystemManagements;
-    uint32_t hwAltivecAssists;
-    uint32_t hwThermal;
-    uint32_t hwSoftPatches;
-    uint32_t hwMaintenances;
-    uint32_t hwInstrumentations;
-} interrupt_counters_t;
-
-extern kern_return_t chudxnu_get_cpu_interrupt_counters(int cpu, interrupt_counters_t *rupts);
-extern kern_return_t chudxnu_clear_cpu_interrupt_counters(int cpu);
-
-#if 0
-#pragma mark **** callbacks ****
-#endif
-// ********************************************************************************
-// callbacks
-// ********************************************************************************
-
-extern void chudxnu_cancel_all_callbacks(void);
-
-// cpu timer - each cpu has its own callback 
-typedef kern_return_t (*chudxnu_cpu_timer_callback_func_t)(thread_flavor_t flavor, thread_state_t tstate,  mach_msg_type_number_t count);
-extern kern_return_t chudxnu_cpu_timer_callback_enter(chudxnu_cpu_timer_callback_func_t func, uint32_t time, uint32_t units); // callback is entered on current cpu
-extern kern_return_t chudxnu_cpu_timer_callback_cancel(void); // callback is cleared on current cpu
-extern kern_return_t chudxnu_cpu_timer_callback_cancel_all(void); // callback is cleared on all cpus
-
-enum {
-    PPC_TRAP_PROGRAM           = 0x700,
-    PPC_TRAP_TRACE             = 0xD00,
-    PPC_TRAP_PERFMON           = 0xF00,
-};
-
-enum {
-       X86_TRAP_DEBUG                  = 0x1,
-};
-
-// trap callback - one callback for system
-typedef kern_return_t (*chudxnu_trap_callback_func_t)(uint32_t trapentry, thread_flavor_t flavor, thread_state_t tstate,  mach_msg_type_number_t count);
-extern kern_return_t chudxnu_trap_callback_enter(chudxnu_trap_callback_func_t func);
-extern kern_return_t chudxnu_trap_callback_cancel(void);
-
-enum {
-    PPC_INTERRUPT_DECREMENTER  = 0x900,
-    PPC_INTERRUPT_INTERRUPT    = 0x500,
-    PPC_INTERRUPT_CPU_SIGNAL   = 0x2200,
-};
-
-enum {
-    X86_INTERRUPT_PERFMON      = 0xB,
-};
-
-// interrupt callback - one callback for system
-typedef kern_return_t (*chudxnu_interrupt_callback_func_t)(uint32_t trapentry, thread_flavor_t flavor, thread_state_t tstate,  mach_msg_type_number_t count);
-extern kern_return_t chudxnu_interrupt_callback_enter(chudxnu_interrupt_callback_func_t func);
-extern kern_return_t chudxnu_interrupt_callback_cancel(void);
-
-// ast callback - one callback for system
-typedef kern_return_t (*chudxnu_perfmon_ast_callback_func_t)(thread_flavor_t flavor, thread_state_t tstate,  mach_msg_type_number_t count);
-extern kern_return_t chudxnu_perfmon_ast_callback_enter(chudxnu_perfmon_ast_callback_func_t func);
-extern kern_return_t chudxnu_perfmon_ast_callback_cancel(void);
-extern kern_return_t chudxnu_perfmon_ast_send_urgent(boolean_t urgent);
-
-// cpusig callback - one callback for system
-typedef kern_return_t (*chudxnu_cpusig_callback_func_t)(int request, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t count);
-extern kern_return_t chudxnu_cpusig_callback_enter(chudxnu_cpusig_callback_func_t func);
-extern kern_return_t chudxnu_cpusig_callback_cancel(void);
-extern kern_return_t chudxnu_cpusig_send(int otherCPU, uint32_t request);
-
-// kdebug callback - one callback for system
-typedef kern_return_t (*chudxnu_kdebug_callback_func_t)(uint32_t debugid, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4);
-extern kern_return_t chudxnu_kdebug_callback_enter(chudxnu_kdebug_callback_func_t func);
-extern kern_return_t chudxnu_kdebug_callback_cancel(void);
-
-// timer callback - multiple callbacks
-typedef kern_return_t (*chudxnu_timer_callback_func_t)(thread_call_param_t param0, thread_call_param_t param1);
-typedef void * chud_timer_t;
-extern chud_timer_t chudxnu_timer_alloc(chudxnu_timer_callback_func_t func, thread_call_param_t param0);
-extern kern_return_t chudxnu_timer_callback_enter(chud_timer_t timer, thread_call_param_t param1, uint32_t time, uint32_t units);
-extern kern_return_t chudxnu_timer_callback_cancel(chud_timer_t timer);
-extern kern_return_t chudxnu_timer_free(chud_timer_t timer);
-
-// CHUD systemcall callback - one callback for system
-typedef kern_return_t (*chudxnu_syscall_callback_func_t)(uint64_t code, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5);
-extern kern_return_t chudxnu_syscall_callback_enter(chudxnu_syscall_callback_func_t func);
-extern kern_return_t chudxnu_syscall_callback_cancel(void);
-
-// ********************************************************************************
-// DEPRECATED
-// ********************************************************************************
-extern kern_return_t chudxnu_thread_get_callstack(thread_t thread, uint32_t *callStack, mach_msg_type_number_t *count, boolean_t user_only);
-
-extern kern_return_t chudxnu_set_shadowed_spr(int cpu, int spr, uint32_t val);
-extern kern_return_t chudxnu_set_shadowed_spr64(int cpu, int spr, uint64_t val);
-
-extern kern_return_t chudxnu_enable_cpu_nap(int cpu, boolean_t enable);
-extern boolean_t chudxnu_cpu_nap_enabled(int cpu);
-
-extern kern_return_t chudxnu_read_spr(int cpu, int spr, uint32_t *val_p);
-extern kern_return_t chudxnu_read_spr64(int cpu, int spr, uint64_t *val_p);
-extern kern_return_t chudxnu_write_spr(int cpu, int spr, uint32_t val);
-extern kern_return_t chudxnu_write_spr64(int cpu, int spr, uint64_t val);
-
-#endif /* _CHUD_XNU_H_ */
diff --git a/osfmk/chud/chud_xnu_glue.h b/osfmk/chud/chud_xnu_glue.h
deleted file mode 100644 (file)
index f595ffe..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *           
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#if defined (__i386__) || defined (__x86_64__)
-#include "i386/chud_xnu_glue.h"
-#elif defined (__arm__)|| defined (__arm64__)
-#include "arm/chud_xnu_glue.h"
-#else
-#error architecture not supported
-#endif
diff --git a/osfmk/chud/chud_xnu_private.h b/osfmk/chud/chud_xnu_private.h
deleted file mode 100644 (file)
index 5a712ac..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#ifndef _CHUD_XNU_PRIVATE_H_
-#define _CHUD_XNU_PRIVATE_H_
-
-#include <stdint.h>
-#include <mach/boolean.h>
-#include <mach/mach_types.h>
-
-#if defined (__i386__) || defined (__x86_64__)
-#include "chud/i386/chud_xnu_private.h"
-#elif defined (__arm__) || defined (__arm64__)
-#include "chud/arm/chud_xnu_private.h"
-#else
-#error architecture not supported
-#endif
-
-#endif /* _CHUD_XNU_PRIVATE_H_ */
diff --git a/osfmk/chud/i386/chud_cpu_i386.c b/osfmk/chud/i386/chud_cpu_i386.c
deleted file mode 100644 (file)
index 564a82c..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2003-2009 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <mach/mach_types.h>
-#include <mach/mach_host.h>
-
-#include <kern/host.h>
-#include <kern/processor.h>
-
-#include <i386/cpu_data.h>
-#include <i386/machine_routines.h>
-#include <i386/lapic.h>
-#include <i386/mp.h>
-#include <i386/trap.h>
-#include <mach/i386/syscall_sw.h>
-
-#include <chud/chud_xnu.h>
-
-#if 0
-#pragma mark **** cpu enable/disable ****
-#endif
-
-extern kern_return_t processor_start(processor_t     processor); // osfmk/kern/processor.c
-extern kern_return_t processor_exit(processor_t     processor); // osfmk/kern/processor.c
-
-__private_extern__
-kern_return_t chudxnu_enable_cpu(int cpu, boolean_t enable)
-{
-    chudxnu_unbind_thread(current_thread(), 0);
-       
-    if(cpu < 0 || (unsigned int)cpu >= real_ncpus) // sanity check
-        return KERN_FAILURE;
-       
-       if((cpu_data_ptr[cpu] != NULL) && cpu != master_cpu) {
-               processor_t processor = cpu_to_processor(cpu);
-               
-               if(processor == master_processor) // don't mess with the boot processor
-                       return KERN_FAILURE;
-
-        if(enable) {
-            return processor_start(processor);
-        } else {
-            return processor_exit(processor);
-        }
-    }
-    return KERN_FAILURE;
-}
-
-#if 0
-#pragma mark **** perfmon facility ****
-#endif
-
-__private_extern__ kern_return_t
-chudxnu_perfmon_acquire_facility(task_t task __unused)
-{
-    return KERN_SUCCESS;
-}
-
-__private_extern__ kern_return_t
-chudxnu_perfmon_release_facility(task_t task __unused)
-{
-    return KERN_SUCCESS;
-}
-
-#if 0
-#pragma mark **** interrupt counters ****
-#endif
-
-__private_extern__ kern_return_t
-chudxnu_get_cpu_interrupt_counters(int cpu, interrupt_counters_t *rupts)
-{
-    if(cpu < 0 || (unsigned int)cpu >= real_ncpus) { // sanity check
-        return KERN_FAILURE;
-    }
-
-    if(rupts) {
-        boolean_t oldlevel = ml_set_interrupts_enabled(FALSE);
-        cpu_data_t     *per_proc;
-
-        per_proc = cpu_data_ptr[cpu];
-               // For now, we'll call an NMI a 'reset' interrupt
-        rupts->hwResets = per_proc->cpu_hwIntCnt[T_NMI];
-        rupts->hwMachineChecks = per_proc->cpu_hwIntCnt[T_MACHINE_CHECK];
-        rupts->hwDSIs = 0;
-        rupts->hwISIs = 0;
-               // we could accumulate 0x20-0x7f, but that'd likely overflow...
-        rupts->hwExternals = 0;
-               // This appears to be wrong.
-        rupts->hwAlignments = 0; //per_proc->cpu_hwIntCnt[0x11];
-        rupts->hwPrograms = 0;
-        rupts->hwFloatPointUnavailable = per_proc->cpu_hwIntCnt[T_NO_FPU];
-               // osfmk/i386/mp.h
-        rupts->hwDecrementers = per_proc->cpu_hwIntCnt[LAPIC_VECTOR(TIMER)];
-               // LAPIC_ERROR == IO ERROR??
-        rupts->hwIOErrors = per_proc->cpu_hwIntCnt[LAPIC_VECTOR(ERROR)];
-
-               // accumulate all system call types
-               // osfmk/mach/i386/syscall_sw.h
-        rupts->hwSystemCalls = per_proc->cpu_hwIntCnt[UNIX_INT]  +
-                       per_proc->cpu_hwIntCnt[MACH_INT] +
-                       per_proc->cpu_hwIntCnt[MACHDEP_INT] +
-                       per_proc->cpu_hwIntCnt[DIAG_INT];
-
-        rupts->hwTraces = per_proc->cpu_hwIntCnt[T_DEBUG]; // single steps == traces??
-        rupts->hwFloatingPointAssists = 0;
-               // osfmk/i386/mp.h
-        rupts->hwPerformanceMonitors =
-                       per_proc->cpu_hwIntCnt[LAPIC_VECTOR(PERFCNT)];
-        rupts->hwAltivecs = 0;
-        rupts->hwInstBreakpoints = per_proc->cpu_hwIntCnt[T_INT3];
-        rupts->hwSystemManagements = 0;
-        rupts->hwAltivecAssists = 0;
-        rupts->hwThermal = per_proc->cpu_hwIntCnt[LAPIC_VECTOR(THERMAL)];
-        rupts->hwSoftPatches = 0;
-        rupts->hwMaintenances = 0;
-               // Watchpoint == instrumentation
-               rupts->hwInstrumentations = per_proc->cpu_hwIntCnt[T_WATCHPOINT]; 
-
-        ml_set_interrupts_enabled(oldlevel);
-        return KERN_SUCCESS;
-    } else {
-        return KERN_FAILURE;
-    }
-}
-
-__private_extern__ kern_return_t
-chudxnu_clear_cpu_interrupt_counters(int cpu)
-{
-    if(cpu < 0 || (unsigned int)cpu >= real_ncpus) { // sanity check
-        return KERN_FAILURE;
-    }
-       cpu_data_t      *per_proc;
-
-       per_proc = cpu_data_ptr[cpu];
-
-       bzero((char *)per_proc->cpu_hwIntCnt, sizeof(uint32_t)*256);
-
-    return KERN_SUCCESS;
-}
-
diff --git a/osfmk/chud/i386/chud_osfmk_callback_i386.c b/osfmk/chud/i386/chud_osfmk_callback_i386.c
deleted file mode 100644 (file)
index f9b5243..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright (c) 2003-2009 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <stdint.h>
-#include <mach/boolean.h>
-#include <mach/mach_types.h>
-
-#include <kern/kern_types.h>
-#include <kern/processor.h>
-#include <kern/timer_call.h>
-#include <kern/thread_call.h>
-#include <kern/kalloc.h>
-#include <kern/thread.h>
-
-#include <libkern/OSAtomic.h>
-
-#include <machine/machine_routines.h>
-#include <machine/cpu_data.h>
-#include <machine/trap.h>
-
-#include <chud/chud_xnu.h>
-#include <chud/chud_xnu_private.h>
-
-#include <i386/misc_protos.h>
-#include <i386/lapic.h>
-#include <i386/mp.h>
-#include <i386/machine_cpu.h>
-
-#include <sys/kdebug.h>
-#define CHUD_TIMER_CALLBACK_CANCEL     0
-#define CHUD_TIMER_CALLBACK_ENTER      1
-#define CHUD_TIMER_CALLBACK            2
-#define CHUD_AST_SEND                  3
-#define CHUD_AST_CALLBACK              4
-#define CHUD_CPUSIG_SEND               5
-#define CHUD_CPUSIG_CALLBACK           6
-
-__private_extern__
-void chudxnu_cancel_all_callbacks(void)
-{
-    chudxnu_cpusig_callback_cancel();
-    chudxnu_cpu_timer_callback_cancel_all();
-    chudxnu_interrupt_callback_cancel();
-    chudxnu_perfmon_ast_callback_cancel();
-}
-
-static lck_grp_t       chud_request_lck_grp;
-static lck_grp_attr_t  chud_request_lck_grp_attr;
-static lck_attr_t      chud_request_lck_attr;
-
-
-static chudcpu_data_t chudcpu_boot_cpu;
-void *
-chudxnu_cpu_alloc(boolean_t boot_processor)
-{
-       chudcpu_data_t  *chud_proc_info;
-
-       if (boot_processor) {
-               chud_proc_info = &chudcpu_boot_cpu;
-
-               lck_attr_setdefault(&chud_request_lck_attr);
-               lck_grp_attr_setdefault(&chud_request_lck_grp_attr);
-               lck_grp_init(&chud_request_lck_grp, "chud_request", &chud_request_lck_grp_attr);
-
-       } else {
-               chud_proc_info = (chudcpu_data_t *)
-                                       kalloc(sizeof(chudcpu_data_t));
-               if (chud_proc_info == (chudcpu_data_t *)NULL) {
-                       return (void *)NULL;
-               }
-       }
-       bzero((char *)chud_proc_info, sizeof(chudcpu_data_t));
-       chud_proc_info->t_deadline = 0xFFFFFFFFFFFFFFFFULL;
-
-       mpqueue_init(&chud_proc_info->cpu_request_queue, &chud_request_lck_grp, &chud_request_lck_attr);
-
-       /* timer_call_cancel() can be called before first usage, so init here: <rdar://problem/9320202> */
-       timer_call_setup(&(chud_proc_info->cpu_timer_call), NULL, NULL);
-
-
-       return (void *)chud_proc_info;
-}
-
-void
-chudxnu_cpu_free(void *cp)
-{
-       if (cp == NULL || cp == (void *)&chudcpu_boot_cpu) {
-               return;
-       } else {
-               kfree(cp,sizeof(chudcpu_data_t));
-       }
-}
-
-static void
-chudxnu_private_cpu_timer_callback(
-       timer_call_param_t param0,
-       timer_call_param_t param1)
-{
-#pragma unused (param0)
-#pragma unused (param1)
-       chudcpu_data_t                  *chud_proc_info;
-       boolean_t                       oldlevel;
-       x86_thread_state_t              state;
-       mach_msg_type_number_t          count;
-       chudxnu_cpu_timer_callback_func_t fn;
-
-       oldlevel = ml_set_interrupts_enabled(FALSE);
-       chud_proc_info = (chudcpu_data_t *)(current_cpu_datap()->cpu_chud);
-
-       count = x86_THREAD_STATE_COUNT;
-       if (chudxnu_thread_get_state(current_thread(),
-                                    x86_THREAD_STATE,
-                                    (thread_state_t)&state,
-                                    &count,
-                                    FALSE) == KERN_SUCCESS) {
-                       fn = chud_proc_info->cpu_timer_callback_fn;
-                       if (fn) {
-                               (fn)(
-                               x86_THREAD_STATE,
-                               (thread_state_t)&state,
-                               count);
-                       } 
-       } 
-       
-       ml_set_interrupts_enabled(oldlevel);
-}
-
-__private_extern__ kern_return_t
-chudxnu_cpu_timer_callback_enter(
-       chudxnu_cpu_timer_callback_func_t       func,
-       uint32_t                                time,
-       uint32_t                                units)
-{
-       chudcpu_data_t  *chud_proc_info;
-       boolean_t       oldlevel;
-
-       oldlevel = ml_set_interrupts_enabled(FALSE);
-       chud_proc_info = (chudcpu_data_t *)(current_cpu_datap()->cpu_chud);
-
-       // cancel any existing callback for this cpu
-       timer_call_cancel(&(chud_proc_info->cpu_timer_call));
-
-       chud_proc_info->cpu_timer_callback_fn = func;
-
-       clock_interval_to_deadline(time, units, &(chud_proc_info->t_deadline));
-       timer_call_setup(&(chud_proc_info->cpu_timer_call),
-                        chudxnu_private_cpu_timer_callback, NULL);
-       timer_call_enter(&(chud_proc_info->cpu_timer_call),
-                        chud_proc_info->t_deadline,
-                        TIMER_CALL_SYS_CRITICAL|TIMER_CALL_LOCAL);
-
-       ml_set_interrupts_enabled(oldlevel);
-       return KERN_SUCCESS;
-}
-
-__private_extern__ kern_return_t
-chudxnu_cpu_timer_callback_cancel(void)
-{
-       chudcpu_data_t  *chud_proc_info;
-       boolean_t       oldlevel;
-
-       oldlevel = ml_set_interrupts_enabled(FALSE);
-       chud_proc_info = (chudcpu_data_t *)(current_cpu_datap()->cpu_chud);
-
-       timer_call_cancel(&(chud_proc_info->cpu_timer_call));
-
-       // set to max value:
-       chud_proc_info->t_deadline |= ~(chud_proc_info->t_deadline);
-       chud_proc_info->cpu_timer_callback_fn = NULL;
-
-       ml_set_interrupts_enabled(oldlevel);
-       return KERN_SUCCESS;
-}
-
-__private_extern__ kern_return_t
-chudxnu_cpu_timer_callback_cancel_all(void)
-{
-       unsigned int    cpu;
-       chudcpu_data_t  *chud_proc_info;
-
-       for(cpu=0; cpu < real_ncpus; cpu++) {
-               chud_proc_info = (chudcpu_data_t *) cpu_data_ptr[cpu]->cpu_chud;
-               if (chud_proc_info == NULL)
-                       continue;
-               timer_call_cancel(&(chud_proc_info->cpu_timer_call));
-               chud_proc_info->t_deadline |= ~(chud_proc_info->t_deadline);
-               chud_proc_info->cpu_timer_callback_fn = NULL;
-       }
-       return KERN_SUCCESS;
-}
-
-#if 0
-#pragma mark **** ast ****
-#endif
-static kern_return_t chud_null_ast(thread_flavor_t flavor, thread_state_t tstate,  
-       mach_msg_type_number_t count);
-static chudxnu_perfmon_ast_callback_func_t perfmon_ast_callback_fn = chud_null_ast;
-
-static kern_return_t chud_null_ast(thread_flavor_t flavor __unused,
-       thread_state_t tstate __unused,  mach_msg_type_number_t count __unused) {
-       return KERN_FAILURE;
-}
-
-static kern_return_t
-chudxnu_private_chud_ast_callback(ast_t reasons, ast_t *myast)
-{      
-       boolean_t oldlevel = ml_set_interrupts_enabled(FALSE);
-       kern_return_t retval = KERN_FAILURE;
-       chudxnu_perfmon_ast_callback_func_t fn = perfmon_ast_callback_fn;
-       
-       if (fn) {
-               if ((*myast & AST_CHUD_URGENT) && (reasons & (AST_URGENT | AST_CHUD_URGENT))) { // Only execute urgent callbacks if reasons specifies an urgent context.
-                       *myast &= ~AST_CHUD_URGENT;
-                       
-                       if (AST_URGENT == *myast) { // If the only flag left is AST_URGENT, we can clear it; we know that we set it, but if there are also other bits set in reasons then someone else might still need AST_URGENT, so we'll leave it set.  The normal machinery in ast_taken will ensure it gets cleared eventually, as necessary.
-                               *myast = AST_NONE;
-                       }
-                       
-                       retval = KERN_SUCCESS;
-               }
-               
-               if ((*myast & AST_CHUD) && (reasons & AST_CHUD)) { // Only execute non-urgent callbacks if reasons actually specifies AST_CHUD.  This implies non-urgent callbacks since the only time this'll happen is if someone either calls ast_taken with AST_CHUD explicitly (not done at time of writing, but possible) or with AST_ALL, which of course includes AST_CHUD.
-                       *myast &= ~AST_CHUD;
-                       retval = KERN_SUCCESS;
-               }
-       
-               if (KERN_SUCCESS == retval) {
-                       x86_thread_state_t state;
-                       mach_msg_type_number_t count = x86_THREAD_STATE_COUNT;
-                       thread_t thread = current_thread();
-                       
-                       if (KERN_SUCCESS == chudxnu_thread_get_state(thread,
-                                                                                                                x86_THREAD_STATE,
-                                                                                                                (thread_state_t)&state,
-                                                                                                                &count,
-                                                                                                                (thread->task != kernel_task))) {
-                               (fn)(x86_THREAD_STATE, (thread_state_t)&state, count);
-                       }
-               }
-       }
-    
-       ml_set_interrupts_enabled(oldlevel);
-       return retval;
-}
-
-volatile perfASTCallback perfASTHook;
-
-__private_extern__ kern_return_t
-chudxnu_perfmon_ast_callback_enter(chudxnu_perfmon_ast_callback_func_t func)
-{
-       if(OSCompareAndSwapPtr(NULL, chudxnu_private_chud_ast_callback,
-               (void * volatile *)&perfASTHook)) {
-               chudxnu_perfmon_ast_callback_func_t old = perfmon_ast_callback_fn;
-
-               while(!OSCompareAndSwapPtr(old, func,
-                       (void * volatile *)&perfmon_ast_callback_fn)) {
-                       old = perfmon_ast_callback_fn;
-               }
-
-               return KERN_SUCCESS;
-       }
-       return KERN_FAILURE;
-}
-
-__private_extern__ kern_return_t
-chudxnu_perfmon_ast_callback_cancel(void)
-{
-       if(OSCompareAndSwapPtr(chudxnu_private_chud_ast_callback, NULL,
-               (void * volatile *)&perfASTHook)) {
-               chudxnu_perfmon_ast_callback_func_t old = perfmon_ast_callback_fn;
-
-               while(!OSCompareAndSwapPtr(old, chud_null_ast,
-                       (void * volatile *)&perfmon_ast_callback_fn)) {
-                       old = perfmon_ast_callback_fn;
-               }
-
-               return KERN_SUCCESS;
-       }
-       return KERN_FAILURE;
-}
-
-__private_extern__ kern_return_t
-chudxnu_perfmon_ast_send_urgent(boolean_t urgent)
-{
-    boolean_t oldlevel = ml_set_interrupts_enabled(FALSE);
-       ast_t *myast = ast_pending();
-
-    if(urgent) {
-        *myast |= (AST_CHUD_URGENT | AST_URGENT);
-    } else {
-        *myast |= (AST_CHUD);
-    }
-
-    ml_set_interrupts_enabled(oldlevel);
-    return KERN_SUCCESS;
-}
-
-#if 0
-#pragma mark **** interrupt ****
-#endif
-static kern_return_t chud_null_int(uint32_t trapentry, thread_flavor_t flavor, 
-       thread_state_t tstate,  mach_msg_type_number_t count);
-static chudxnu_interrupt_callback_func_t interrupt_callback_fn = chud_null_int;
-
-static kern_return_t chud_null_int(uint32_t trapentry __unused, thread_flavor_t flavor __unused,
-       thread_state_t tstate __unused,  mach_msg_type_number_t count __unused) {
-       return KERN_FAILURE;
-}
-
-static void
-chudxnu_private_interrupt_callback(void *foo) __attribute__((used));
-
-static void
-chudxnu_private_interrupt_callback(void *foo)
-{
-#pragma unused (foo)
-       chudxnu_interrupt_callback_func_t fn = interrupt_callback_fn;
-
-       if(fn) {
-               boolean_t                       oldlevel;
-               x86_thread_state_t              state;
-               mach_msg_type_number_t          count;
-
-               oldlevel = ml_set_interrupts_enabled(FALSE);
-
-               count = x86_THREAD_STATE_COUNT;
-               if(chudxnu_thread_get_state(current_thread(),
-                                           x86_THREAD_STATE,
-                                           (thread_state_t)&state,
-                                           &count,
-                                           FALSE) == KERN_SUCCESS) {
-                       (fn)(
-                               X86_INTERRUPT_PERFMON,
-                               x86_THREAD_STATE,
-                               (thread_state_t)&state,
-                               count);
-               }
-               ml_set_interrupts_enabled(oldlevel);
-       }
-}
-
-__private_extern__ kern_return_t
-chudxnu_interrupt_callback_enter(chudxnu_interrupt_callback_func_t func)
-{
-       if(OSCompareAndSwapPtr(chud_null_int, func, 
-               (void * volatile *)&interrupt_callback_fn)) {
-               lapic_set_pmi_func((i386_intr_func_t)chudxnu_private_interrupt_callback);
-               return KERN_SUCCESS;
-       }
-    return KERN_FAILURE;
-}
-
-__private_extern__ kern_return_t
-chudxnu_interrupt_callback_cancel(void)
-{
-       chudxnu_interrupt_callback_func_t old = interrupt_callback_fn;
-
-       while(!OSCompareAndSwapPtr(old, chud_null_int,
-               (void * volatile *)&interrupt_callback_fn)) {
-               old = interrupt_callback_fn;
-       }
-
-    lapic_set_pmi_func(NULL);
-    return KERN_SUCCESS;
-}
-
-#if 0
-#pragma mark **** cpu signal ****
-#endif
-static chudxnu_cpusig_callback_func_t cpusig_callback_fn = NULL;
-
-static          kern_return_t
-chudxnu_private_cpu_signal_handler(int request)
-{
-       chudxnu_cpusig_callback_func_t fn = cpusig_callback_fn;
-       
-       if (fn) {
-       x86_thread_state_t  state;
-               mach_msg_type_number_t count = x86_THREAD_STATE_COUNT;
-
-               if (chudxnu_thread_get_state(current_thread(),
-                                            x86_THREAD_STATE,
-                                            (thread_state_t) &state, &count,
-                                            FALSE) == KERN_SUCCESS) {
-                       return (fn)(
-                                       request, x86_THREAD_STATE,
-                                       (thread_state_t) &state, count);
-               } else {
-                       return KERN_FAILURE;
-               }
-       }
-       return KERN_SUCCESS; //ignored
-}
-/*
- * chudxnu_cpu_signal_handler() is called from the IPI handler
- * when a CHUD signal arrives from another processor.
- */
-__private_extern__ void
-chudxnu_cpu_signal_handler(void)
-{
-       chudcpu_signal_request_t        *reqp;
-       chudcpu_data_t                  *chudinfop;
-
-       chudinfop = (chudcpu_data_t *) current_cpu_datap()->cpu_chud;
-
-       mpdequeue_head(&(chudinfop->cpu_request_queue),
-                      (queue_entry_t *) &reqp);
-       while (reqp != NULL) {
-               chudxnu_private_cpu_signal_handler(reqp->req_code);
-               reqp->req_sync = 0;
-               mpdequeue_head(&(chudinfop->cpu_request_queue),
-                              (queue_entry_t *) &reqp);
-       }
-}
-
-__private_extern__ kern_return_t
-chudxnu_cpusig_callback_enter(chudxnu_cpusig_callback_func_t func)
-{
-       if(OSCompareAndSwapPtr(NULL, func, 
-               (void * volatile *)&cpusig_callback_fn)) {
-               return KERN_SUCCESS;
-       }
-       return KERN_FAILURE;
-}
-
-__private_extern__ kern_return_t
-chudxnu_cpusig_callback_cancel(void)
-{
-       chudxnu_cpusig_callback_func_t old = cpusig_callback_fn;
-
-       while(!OSCompareAndSwapPtr(old, NULL,
-               (void * volatile *)&cpusig_callback_fn)) {
-               old = cpusig_callback_fn;
-       }
-
-       return KERN_SUCCESS;
-}
-
-__private_extern__ kern_return_t
-chudxnu_cpusig_send(int otherCPU, uint32_t request_code)
-{
-       int                             thisCPU;
-       kern_return_t                   retval = KERN_FAILURE;
-       chudcpu_signal_request_t        request;
-       uint64_t                        deadline;
-       chudcpu_data_t                  *target_chudp;
-       boolean_t old_level;
-
-       disable_preemption();
-       // force interrupts on for a cross CPU signal.
-       old_level = chudxnu_set_interrupts_enabled(TRUE);
-       thisCPU = cpu_number();
-
-       if ((unsigned) otherCPU < real_ncpus &&
-           thisCPU != otherCPU &&
-           cpu_data_ptr[otherCPU]->cpu_running) {
-
-               target_chudp = (chudcpu_data_t *)
-                                       cpu_data_ptr[otherCPU]->cpu_chud;
-
-               /* Fill out request */
-               request.req_sync = 0xFFFFFFFF;          /* set sync flag */
-               //request.req_type = CPRQchud;          /* set request type */
-               request.req_code = request_code;        /* set request */
-
-               /*
-                * Insert the new request in the target cpu's request queue
-                * and signal target cpu.
-                */
-               mpenqueue_tail(&target_chudp->cpu_request_queue,
-                              &request.req_entry);
-               i386_signal_cpu(otherCPU, MP_CHUD, ASYNC);
-
-               /* Wait for response or timeout */
-               deadline = mach_absolute_time() + LockTimeOut;
-               while (request.req_sync != 0) {
-                       if (mach_absolute_time() > deadline) {
-                               panic("chudxnu_cpusig_send(%d,%d) timed out\n",
-                                       otherCPU, request_code);
-                       }
-                       cpu_pause();
-               }
-               retval = KERN_SUCCESS;
-       } else {
-               retval = KERN_INVALID_ARGUMENT;
-       }
-
-       chudxnu_set_interrupts_enabled(old_level);
-       enable_preemption();
-       return retval;
-}
diff --git a/osfmk/chud/i386/chud_thread_i386.c b/osfmk/chud/i386/chud_thread_i386.c
deleted file mode 100644 (file)
index ba2a187..0000000
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <mach/mach_types.h>
-#include <mach/task.h>
-#include <mach/thread_act.h>
-#include <machine/thread.h>
-
-#include <kern/kern_types.h>
-#include <kern/processor.h>
-#include <kern/thread.h>
-
-#include <vm/vm_map.h>
-#include <vm/pmap.h>
-
-#include <chud/chud_xnu.h>
-#include <chud/chud_xnu_private.h>
-
-#include <i386/proc_reg.h>
-#include <i386/mp_desc.h>
-#include <i386/misc_protos.h>
-
-#if 0
-#pragma mark **** thread state ****
-#endif
-
-__private_extern__ kern_return_t
-chudxnu_thread_get_state(
-                                                thread_t               thread, 
-                                                thread_flavor_t                flavor,
-                                                thread_state_t         tstate,
-                                                mach_msg_type_number_t *count,
-                                                boolean_t              user_only)
-{
-       if (user_only) {
-               /* We can't get user state for kernel threads */
-               if (thread->task == kernel_task)
-                       return KERN_FAILURE;
-               /* this properly handles deciding whether or not the thread is 64 bit or not */
-               return machine_thread_get_state(thread, flavor, tstate, count);
-       } else {
-               // i386 machine_thread_get_kern_state() is different from the PPC version which returns
-               // the previous save area - user or kernel - rather than kernel or NULL if no kernel
-               // interrupt state available
-               
-               // the real purpose of this branch is the following:
-               // the user doesn't care if the thread states are user or kernel, he
-               // just wants the thread state, so we need to determine the proper one
-               // to return, kernel or user, for the given thread.
-               if(thread == current_thread() && current_cpu_datap()->cpu_int_state) {
-                       // the above are conditions where we possibly can read the kernel
-                       // state. we still need to determine if this interrupt happened in
-                       // kernel or user context
-                       if(USER_STATE(thread) == current_cpu_datap()->cpu_int_state &&
-                          current_cpu_datap()->cpu_interrupt_level == 1) {
-                               // interrupt happened in user land
-                               return machine_thread_get_state(thread, flavor, tstate, count);
-                       } else {
-                               // kernel interrupt.
-                               return machine_thread_get_kern_state(thread, flavor, tstate, count);
-                       }
-               } else {
-            // get the user-mode thread state
-                       return machine_thread_get_state(thread, flavor, tstate, count);
-               }
-       }
-}
-
-__private_extern__ kern_return_t
-chudxnu_thread_set_state(
-                                                thread_t               thread, 
-                                                thread_flavor_t                flavor,
-                                                thread_state_t         tstate,
-                                                mach_msg_type_number_t count,
-                                                boolean_t              user_only)
-{
-#pragma unused (user_only)
-       return machine_thread_set_state(thread, flavor, tstate, count);
-}
-
-#if 0
-#pragma mark **** task memory read/write ****
-#endif
-
-__private_extern__ kern_return_t
-chudxnu_task_read(
-                                 task_t                task,
-                                 void          *kernaddr,
-                                 uint64_t      usraddr,
-                                 vm_size_t     size)
-{
-       kern_return_t ret = KERN_SUCCESS;
-       boolean_t old_level;
-       
-       if(ml_at_interrupt_context()) {
-               return KERN_FAILURE; // Can't look at tasks on interrupt stack
-       }
-
-       /*
-        * pmap layer requires interrupts to be on
-        */
-       old_level = ml_set_interrupts_enabled(TRUE);
-       
-       if(current_task()==task) {      
-               
-               if(copyin(usraddr, kernaddr, size)) {
-                       ret = KERN_FAILURE;
-               }
-       } else {
-               vm_map_t map = get_task_map(task);
-               ret = vm_map_read_user(map, usraddr, kernaddr, size);
-       }
-    
-       ml_set_interrupts_enabled(old_level);
-
-       return ret;
-}
-
-__private_extern__ kern_return_t
-chudxnu_task_write(
-                                  task_t               task,
-                                  uint64_t     useraddr,
-                                  void         *kernaddr,
-                                  vm_size_t    size)
-{
-       kern_return_t ret = KERN_SUCCESS;
-       boolean_t old_level;
-       
-       if(ml_at_interrupt_context()) {
-               return KERN_FAILURE; // can't poke into tasks on interrupt stack
-       }
-
-       /*
-        * pmap layer requires interrupts to be on
-        */
-       old_level = ml_set_interrupts_enabled(TRUE);
-       
-       if(current_task()==task) {    
-               
-               if(copyout(kernaddr, useraddr, size)) {
-                       ret = KERN_FAILURE;
-               }
-       } else {
-               vm_map_t map = get_task_map(task);
-               ret = vm_map_write_user(map, kernaddr, useraddr, size);
-       }               
-       
-       ml_set_interrupts_enabled(old_level);
-
-       return ret;
-}
-
-__private_extern__ kern_return_t
-chudxnu_kern_read(void *dstaddr, vm_offset_t srcaddr, vm_size_t size)
-{
-       return (ml_nofault_copy(srcaddr, (vm_offset_t) dstaddr, size) == size ?
-                       KERN_SUCCESS: KERN_FAILURE);
-}
-
-__private_extern__ kern_return_t
-chudxnu_kern_write(
-                                  vm_offset_t  dstaddr,
-                                  void         *srcaddr,
-                                  vm_size_t    size)
-{
-       return (ml_nofault_copy((vm_offset_t) srcaddr, dstaddr, size) == size ?
-                       KERN_SUCCESS: KERN_FAILURE);
-}
-
-#define VALID_STACK_ADDRESS(supervisor, addr, minKernAddr, maxKernAddr)   (supervisor ? (addr>=minKernAddr && addr<=maxKernAddr) : TRUE)
-// don't try to read in the hole
-#define VALID_STACK_ADDRESS64(supervisor, addr, minKernAddr, maxKernAddr) \
-(supervisor ? ((uint64_t)addr >= minKernAddr && (uint64_t)addr <= maxKernAddr) : \
-((uint64_t)addr != 0ULL && ((uint64_t)addr <= 0x00007FFFFFFFFFFFULL || (uint64_t)addr >= 0xFFFF800000000000ULL)))
-
-typedef struct _cframe64_t {
-       uint64_t        prevFP;         // can't use a real pointer here until we're a 64 bit kernel
-       uint64_t        caller;
-       uint64_t        args[0];
-}cframe64_t;
-
-
-typedef struct _cframe_t {
-       uint32_t                prev;   // this is really a user32-space pointer to the previous frame
-       uint32_t                caller;
-       uint32_t                args[0];
-} cframe_t;
-
-extern void * find_user_regs(thread_t);
-extern x86_saved_state32_t *find_kern_regs(thread_t);
-
-static kern_return_t do_backtrace32(
-       task_t task,
-       thread_t thread,
-       x86_saved_state32_t *regs, 
-       uint64_t *frames,
-       mach_msg_type_number_t *start_idx,
-       mach_msg_type_number_t max_idx,
-       boolean_t supervisor)
-{
-       uint32_t tmpWord = 0UL;
-       uint64_t currPC = (uint64_t) regs->eip;
-       uint64_t currFP = (uint64_t) regs->ebp;
-       uint64_t prevPC = 0ULL;
-       uint64_t prevFP = 0ULL;
-       uint64_t kernStackMin = thread->kernel_stack;
-    uint64_t kernStackMax = kernStackMin + kernel_stack_size;
-       mach_msg_type_number_t ct = *start_idx;
-       kern_return_t kr = KERN_FAILURE;
-
-       if(ct >= max_idx)
-               return KERN_RESOURCE_SHORTAGE;  // no frames traced
-       
-       frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
-
-       // build a backtrace of this 32 bit state.
-       while(VALID_STACK_ADDRESS(supervisor, currFP, kernStackMin, kernStackMax)) {
-               cframe_t *fp = (cframe_t *) (uintptr_t) currFP;
-
-        if(!currFP) {
-            currPC = 0;
-            break;
-        }
-
-        if(ct >= max_idx) {
-                       *start_idx = ct;
-            return KERN_RESOURCE_SHORTAGE;
-        }
-
-               /* read our caller */
-               if(supervisor) {
-                       kr = chudxnu_kern_read(&tmpWord, (vm_offset_t) &fp->caller, sizeof(uint32_t));
-               } else {
-                       kr = chudxnu_task_read(task, &tmpWord, (vm_offset_t) &fp->caller, sizeof(uint32_t));
-               }
-
-               if(kr != KERN_SUCCESS) {
-                       currPC = 0ULL;
-                       break;
-               }
-
-               currPC = (uint64_t) tmpWord;    // promote 32 bit address
-
-        /* 
-         * retrive contents of the frame pointer and advance to the next stack
-         * frame if it's valid 
-         */
-        prevFP = 0;
-               if(supervisor) {
-                       kr = chudxnu_kern_read(&tmpWord, (vm_offset_t)&fp->prev, sizeof(uint32_t));
-               } else {
-                       kr = chudxnu_task_read(task, &tmpWord, (vm_offset_t)&fp->prev, sizeof(uint32_t));
-               }
-               prevFP = (uint64_t) tmpWord;    // promote 32 bit address
-
-        if(prevFP) {
-            frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
-            prevPC = currPC;
-        }
-        if(prevFP < currFP) {
-            break;
-        } else {
-            currFP = prevFP;
-        }      
-       }
-
-       *start_idx = ct;
-       return KERN_SUCCESS;
-}
-
-static kern_return_t do_backtrace64(
-       task_t task,
-       thread_t thread,
-       x86_saved_state64_t *regs, 
-       uint64_t *frames,
-       mach_msg_type_number_t *start_idx,
-       mach_msg_type_number_t max_idx,
-       boolean_t supervisor)
-{
-       uint64_t currPC = regs->isf.rip;
-       uint64_t currFP = regs->rbp;
-       uint64_t prevPC = 0ULL;
-       uint64_t prevFP = 0ULL;
-       uint64_t kernStackMin = (uint64_t)thread->kernel_stack;
-    uint64_t kernStackMax = (uint64_t)kernStackMin + kernel_stack_size;
-       mach_msg_type_number_t ct = *start_idx;
-       kern_return_t kr = KERN_FAILURE;
-
-       if(*start_idx >= max_idx)
-               return KERN_RESOURCE_SHORTAGE;  // no frames traced
-       
-       frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
-
-       // build a backtrace of this 32 bit state.
-       while(VALID_STACK_ADDRESS64(supervisor, currFP, kernStackMin, kernStackMax)) {
-               // this is the address where caller lives in the user thread
-               uint64_t caller = currFP + sizeof(uint64_t);
-
-        if(!currFP) {
-            currPC = 0;
-            break;
-        }
-
-        if(ct >= max_idx) {
-                       *start_idx = ct;
-            return KERN_RESOURCE_SHORTAGE;
-        }
-
-               /* read our caller */
-               if(supervisor) {
-                       kr = chudxnu_kern_read(&currPC, (vm_offset_t)caller, sizeof(uint64_t));
-               } else {
-                       kr = chudxnu_task_read(task, &currPC, caller, sizeof(uint64_t));
-               }
-
-               if(kr != KERN_SUCCESS) {
-                       currPC = 0ULL;
-                       break;
-               }
-
-        /* 
-         * retrive contents of the frame pointer and advance to the next stack
-         * frame if it's valid 
-         */
-        prevFP = 0;
-               if(supervisor) {
-                       kr = chudxnu_kern_read(&prevFP, (vm_offset_t)currFP, sizeof(uint64_t));
-               } else {
-                       kr = chudxnu_task_read(task, &prevFP, currFP, sizeof(uint64_t));
-               }
-
-        if(VALID_STACK_ADDRESS64(supervisor, prevFP, kernStackMin, kernStackMax)) {
-            frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
-            prevPC = currPC;
-        }
-        if(prevFP < currFP) {
-            break;
-        } else {
-            currFP = prevFP;
-        }      
-       }
-
-       *start_idx = ct;
-       return KERN_SUCCESS;
-}
-
-static kern_return_t do_kernel_backtrace(
-       thread_t thread,
-       struct x86_kernel_state *regs, 
-       uint64_t *frames,
-       mach_msg_type_number_t *start_idx,
-       mach_msg_type_number_t max_idx)
-{
-       uint64_t kernStackMin = (uint64_t)thread->kernel_stack;
-    uint64_t kernStackMax = (uint64_t)kernStackMin + kernel_stack_size;
-       mach_msg_type_number_t ct = *start_idx;
-       kern_return_t kr = KERN_FAILURE;
-
-#if __LP64__
-       uint64_t currPC = 0ULL;
-       uint64_t currFP = 0ULL;
-       uint64_t prevPC = 0ULL;
-       uint64_t prevFP = 0ULL;
-       if(KERN_SUCCESS != chudxnu_kern_read(&currPC, (vm_offset_t)&(regs->k_rip), sizeof(uint64_t))) {
-               return KERN_FAILURE;
-       }
-       if(KERN_SUCCESS != chudxnu_kern_read(&currFP, (vm_offset_t)&(regs->k_rbp), sizeof(uint64_t))) {
-               return KERN_FAILURE;
-       }
-#else
-       uint32_t currPC = 0U;
-       uint32_t currFP = 0U;
-       uint32_t prevPC = 0U;
-       uint32_t prevFP = 0U;
-       if(KERN_SUCCESS != chudxnu_kern_read(&currPC, (vm_offset_t)&(regs->k_eip), sizeof(uint32_t))) {
-               return KERN_FAILURE;
-       }
-       if(KERN_SUCCESS != chudxnu_kern_read(&currFP, (vm_offset_t)&(regs->k_ebp), sizeof(uint32_t))) {
-               return KERN_FAILURE;
-       }
-#endif
-
-       if(*start_idx >= max_idx)
-               return KERN_RESOURCE_SHORTAGE;  // no frames traced
-       
-       if(!currPC) {
-               return KERN_FAILURE;
-       }
-
-       frames[ct++] = chudxnu_vm_unslide((uint64_t)currPC, 1);
-
-       // build a backtrace of this kernel state
-#if __LP64__
-       while(VALID_STACK_ADDRESS64(TRUE, currFP, kernStackMin, kernStackMax)) {
-               // this is the address where caller lives in the user thread
-               uint64_t caller = currFP + sizeof(uint64_t);
-#else
-       while(VALID_STACK_ADDRESS(TRUE, currFP, kernStackMin, kernStackMax)) {
-               uint32_t caller = (uint32_t)currFP + sizeof(uint32_t);
-#endif
-
-        if(!currFP || !currPC) {
-            currPC = 0;
-            break;
-        }
-
-        if(ct >= max_idx) {
-                       *start_idx = ct;
-            return KERN_RESOURCE_SHORTAGE;
-        }
-
-               /* read our caller */
-               kr = chudxnu_kern_read(&currPC, (vm_offset_t)caller, sizeof(currPC));
-
-               if(kr != KERN_SUCCESS || !currPC) {
-                       currPC = 0UL;
-                       break;
-               }
-
-        /* 
-         * retrive contents of the frame pointer and advance to the next stack
-         * frame if it's valid 
-         */
-        prevFP = 0;
-               kr = chudxnu_kern_read(&prevFP, (vm_offset_t)currFP, sizeof(currPC));
-
-#if __LP64__
-        if(VALID_STACK_ADDRESS64(TRUE, prevFP, kernStackMin, kernStackMax)) {
-#else
-        if(VALID_STACK_ADDRESS(TRUE, prevFP, kernStackMin, kernStackMax)) {
-#endif
-            frames[ct++] = chudxnu_vm_unslide((uint64_t)currPC, 1);
-            prevPC = currPC;
-        }
-        if(prevFP <= currFP) {
-            break;
-        } else {
-            currFP = prevFP;
-        }      
-       }
-
-       *start_idx = ct;
-       return KERN_SUCCESS;
-}
-
-static
-kern_return_t chudxnu_thread_get_callstack64_internal(
-       thread_t                thread,
-       uint64_t                *callstack,
-       mach_msg_type_number_t  *count,
-       boolean_t               user_only,
-       boolean_t               kern_only)
-{
-       kern_return_t kr = KERN_FAILURE;
-    task_t task = thread->task;
-    uint64_t currPC = 0ULL;
-       boolean_t supervisor = FALSE;
-    mach_msg_type_number_t bufferIndex = 0;
-    mach_msg_type_number_t bufferMaxIndex = *count;
-       x86_saved_state_t *tagged_regs = NULL;          // kernel register state
-       x86_saved_state64_t *regs64 = NULL;
-       x86_saved_state32_t *regs32 = NULL;
-       x86_saved_state32_t *u_regs32 = NULL;
-       x86_saved_state64_t *u_regs64 = NULL;
-       struct x86_kernel_state *kregs = NULL;
-
-       if(ml_at_interrupt_context()) {
-               
-               if(user_only) {
-                       /* can't backtrace user state on interrupt stack. */
-                       return KERN_FAILURE;
-               }
-
-               /* backtracing at interrupt context? */
-                if(thread == current_thread() && current_cpu_datap()->cpu_int_state) {
-                       /* 
-                        * Locate the registers for the interrupted thread, assuming it is
-                        * current_thread(). 
-                        */
-                       tagged_regs = current_cpu_datap()->cpu_int_state;
-                       
-                       if(is_saved_state64(tagged_regs)) {
-                               /* 64 bit registers */
-                               regs64 = saved_state64(tagged_regs);
-                               supervisor = ((regs64->isf.cs & SEL_PL) != SEL_PL_U);
-                       } else {
-                               /* 32 bit registers */
-                               regs32 = saved_state32(tagged_regs);
-                               supervisor = ((regs32->cs & SEL_PL) != SEL_PL_U);
-                       }
-               } 
-       }
-
-       if(!ml_at_interrupt_context() && kernel_task == task) {
-
-               if(!thread->kernel_stack) {
-                       return KERN_FAILURE;
-               }
-
-               // Kernel thread not at interrupt context
-               kregs = (struct x86_kernel_state *)NULL;
-
-               // nofault read of the thread->kernel_stack pointer
-               if(KERN_SUCCESS != chudxnu_kern_read(&kregs, (vm_offset_t)&(thread->kernel_stack), sizeof(void *))) {
-                       return KERN_FAILURE;
-               }
-
-               // Adjust to find the saved kernel state
-               kregs = STACK_IKS((vm_offset_t)(uintptr_t)kregs);
-
-               supervisor = TRUE;
-       } else if(!tagged_regs) {
-               /* 
-                * not at interrupt context, or tracing a different thread than
-                * current_thread() at interrupt context 
-                */
-               tagged_regs = USER_STATE(thread);
-               if(is_saved_state64(tagged_regs)) {
-                       /* 64 bit registers */
-                       regs64 = saved_state64(tagged_regs);
-                       supervisor = ((regs64->isf.cs & SEL_PL) != SEL_PL_U); 
-               } else {
-                       /* 32 bit registers */
-                       regs32 = saved_state32(tagged_regs);
-                       supervisor = ((regs32->cs & SEL_PL) != SEL_PL_U);
-               }
-       }
-
-       *count = 0; 
-
-       if(supervisor) {
-               // the caller only wants a user callstack.
-               if(user_only) {
-                       // bail - we've only got kernel state
-                       return KERN_FAILURE;
-               }
-       } else {
-               // regs32(64) is not in supervisor mode.
-               u_regs32 = regs32;
-               u_regs64 = regs64;
-               regs32 = NULL;
-               regs64 = NULL;
-       }
-
-       if (user_only) {
-               /* we only want to backtrace the user mode */
-               if(!(u_regs32 || u_regs64)) {
-                       /* no user state to look at */
-                       return KERN_FAILURE;
-               }
-       }
-
-       /* 
-        * Order of preference for top of stack:
-        * 64 bit kernel state (not likely)
-        * 32 bit kernel state
-        * 64 bit user land state
-        * 32 bit user land state
-        */
-
-       if(kregs) {
-               /*
-                * nofault read of the registers from the kernel stack (as they can
-                * disappear on the fly).
-                */
-
-#if __LP64__
-               if(KERN_SUCCESS != chudxnu_kern_read(&currPC, (vm_offset_t)&(kregs->k_rip), sizeof(uint64_t))) {
-                       return KERN_FAILURE;
-               }
-#else
-               uint32_t tmp;
-               if(KERN_SUCCESS != chudxnu_kern_read(&tmp, (vm_offset_t)&(kregs->k_eip), sizeof(uint32_t))) {
-                       return KERN_FAILURE;
-               }
-               currPC = (uint64_t)tmp;
-#endif
-       } else if(regs64) {
-               currPC = regs64->isf.rip;
-       } else if(regs32) {
-               currPC = (uint64_t) regs32->eip;
-       } else if(u_regs64) {
-               currPC = u_regs64->isf.rip;
-       } else if(u_regs32) {
-               currPC = (uint64_t) u_regs32->eip;
-       }
-       
-       if(!currPC) {
-               /* no top of the stack, bail out */
-               return KERN_FAILURE;
-       }
-
-       bufferIndex = 0;
-               
-       if(bufferMaxIndex < 1) {
-               *count = 0;
-               return KERN_RESOURCE_SHORTAGE;
-       }
-
-       /* backtrace kernel */
-       if(kregs) {
-               addr64_t address = 0ULL;
-               size_t size = 0UL;
-
-               // do the backtrace
-               kr = do_kernel_backtrace(thread, kregs, callstack, &bufferIndex, bufferMaxIndex);
-
-               // and do a nofault read of (r|e)sp
-#if __LP64__
-               uint64_t rsp = 0ULL;
-               size = sizeof(uint64_t);
-               
-               if(KERN_SUCCESS != chudxnu_kern_read(&address, (vm_offset_t)&(kregs->k_rsp), size)) {
-                       address = 0ULL;
-               }
-#else
-               uint32_t rsp = 0ULL, tmp = 0ULL;
-               size = sizeof(uint32_t);
-
-               if(KERN_SUCCESS != chudxnu_kern_read(&tmp, (vm_offset_t)&(kregs->k_esp), size)) {
-                       address = 0ULL;
-               } else {
-                       address = (addr64_t)tmp;
-               }
-#endif
-
-               if(address && KERN_SUCCESS == chudxnu_kern_read(&rsp, (vm_offset_t)address, size) && bufferIndex < bufferMaxIndex) {
-                       callstack[bufferIndex++] = (uint64_t)rsp;
-               }
-       } else if(regs64) {
-               uint64_t rsp = 0ULL;
-
-               // backtrace the 64bit side.
-               kr = do_backtrace64(task, thread, regs64, callstack, &bufferIndex,
-                                   bufferMaxIndex - 1, TRUE);
-
-               if(KERN_SUCCESS == chudxnu_kern_read(&rsp, (vm_offset_t) regs64->isf.rsp, sizeof(uint64_t)) && 
-                       bufferIndex < bufferMaxIndex) {
-                       callstack[bufferIndex++] = rsp;
-               }
-
-       } else if(regs32) {
-               uint32_t esp = 0UL;
-
-               // backtrace the 32bit side.
-               kr = do_backtrace32(task, thread, regs32, callstack, &bufferIndex,
-                                   bufferMaxIndex - 1, TRUE);
-               
-               if(KERN_SUCCESS == chudxnu_kern_read(&esp, (vm_offset_t) regs32->uesp, sizeof(uint32_t)) && 
-                       bufferIndex < bufferMaxIndex) {
-                       callstack[bufferIndex++] = (uint64_t) esp;
-               }
-       } else if(u_regs64 && !kern_only) {
-               /* backtrace user land */
-               uint64_t rsp = 0ULL;
-               
-               kr = do_backtrace64(task, thread, u_regs64, callstack, &bufferIndex,
-                                   bufferMaxIndex - 1, FALSE);
-
-               if(KERN_SUCCESS == chudxnu_task_read(task, &rsp, (addr64_t) u_regs64->isf.rsp, sizeof(uint64_t)) && 
-                       bufferIndex < bufferMaxIndex) {
-                       callstack[bufferIndex++] = rsp;
-               }
-
-       } else if(u_regs32 && !kern_only) {
-               uint32_t esp = 0UL;
-               
-               kr = do_backtrace32(task, thread, u_regs32, callstack, &bufferIndex,
-                                   bufferMaxIndex - 1, FALSE);
-
-               if(KERN_SUCCESS == chudxnu_task_read(task, &esp, (addr64_t) u_regs32->uesp, sizeof(uint32_t)) && 
-                       bufferIndex < bufferMaxIndex) {
-                       callstack[bufferIndex++] = (uint64_t) esp;
-               }
-       }
-
-    *count = bufferIndex;
-    return kr;
-}
-
-__private_extern__
-kern_return_t chudxnu_thread_get_callstack64_kperf(
-       thread_t                thread,
-       uint64_t                *callstack,
-       mach_msg_type_number_t  *count,
-       boolean_t               is_user)
-{
-       return chudxnu_thread_get_callstack64_internal(thread, callstack, count, is_user, !is_user);
-}
-
-__private_extern__
-kern_return_t chudxnu_thread_get_callstack64(
-       thread_t                thread,
-       uint64_t                *callstack,
-       mach_msg_type_number_t  *count,
-       boolean_t               user_only)
-{
-       return chudxnu_thread_get_callstack64_internal(thread, callstack, count, user_only, 0);
-}
-
diff --git a/osfmk/chud/i386/chud_xnu_glue.h b/osfmk/chud/i386/chud_xnu_glue.h
deleted file mode 100644 (file)
index 7145052..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2003-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
diff --git a/osfmk/chud/i386/chud_xnu_private.h b/osfmk/chud/i386/chud_xnu_private.h
deleted file mode 100644 (file)
index 4d0a303..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#ifndef _I386_CHUD_XNU_PRIVATE_H_
-#define _I386_CHUD_XNU_PRIVATE_H_
-
-#include <kern/queue.h>
-
-#if 0
-#pragma mark **** cpu timer ****
-#endif
-
-/*
- * Cross-cpu signal request entries are queued on the target cpu's
- * chudcpu_data_t struct. This differs from PPC because i386 doesn't
- * support sending arguments with cross-cpu signals. Hence we have
- * to do it ourselves.
- */ 
-typedef struct {
-       struct queue_entry req_entry;   /* Must be first */
-       uint32_t req_type;
-       uint32_t req_code;
-       volatile uint32_t req_sync;
-} chudcpu_signal_request_t;
-
-typedef struct {
-       void                                    *cpu_chud_fn_tablep;
-       timer_call_data_t               cpu_timer_call;
-       uint64_t                                t_deadline;
-       chudxnu_cpu_timer_callback_func_t       cpu_timer_callback_fn;
-       mpqueue_head_t                  cpu_request_queue;
-} chudcpu_data_t;
-/* NB: cpu_chud_fn_tablep is expected to be the first member, at offset 0 */
-
-extern void chudxnu_cpu_signal_handler(void);
-
-#endif /* _I386_CHUD_XNU_PRIVATE_H_ */
index b1f41bbc2efef83b6c53dec08f2031558068e5c9..d533b91a5edc755fedf2ce4da319c2e6b71a2af9 100644 (file)
@@ -23,8 +23,6 @@ SFLAGS+= -include meta_features.h
 OBJS_NO_CAST_ALIGN =                   \
                atm_notification_user.o \
                model_dep.o             \
-               chud_thread.o           \
-               chud_thread_arm.o       \
                video_console.o         \
                kdp_udp.o               \
                kdp_machdep.o           \
@@ -92,11 +90,6 @@ OBJS_NO_SIGN_COMPARE =               \
 $(foreach file,$(OBJS_NO_CAST_ALIGN),$(eval $(call add_perfile_cflags,$(file),-Wno-cast-align)))
 $(foreach file,$(OBJS_NO_SIGN_COMPARE),$(eval $(call add_perfile_cflags,$(file),-Wno-sign-compare)))
 
-#
-# Do not provide CTF symbolic these files
-#
-chud_glue.o_SKIP_CTFCONVERT = 1
-
 #
 # XXX: INCFLAGS to include libsa prototypes
 #
index befcee59c054867c228f8bcbbf7e4e7c6accc03e..53078380e40844eb86192a5ab77e83f63df7614a 100644 (file)
@@ -270,15 +270,6 @@ osfmk/kern/kmod.c                  standard
 #
 osfmk/device/subrs.c                   standard
 
-#
-# MI CHUD:
-#
-osfmk/chud/chud_cpu.c                  standard
-osfmk/chud/chud_glue.c                 standard
-osfmk/chud/chud_memory.c               standard
-osfmk/chud/chud_osfmk_callback.c       standard
-osfmk/chud/chud_thread.c               standard
-
 # Kernel performance monitoring
 osfmk/kperf/kperf.c                     optional kperf
 osfmk/kperf/action.c                    optional kperf
index d79408fda3c22526a216e03a9c7db2bdef9e59ec..208781e4709af256362fa48e1443483bcbd5482b 100644 (file)
@@ -61,7 +61,6 @@ osfmk/arm/commpage/commpage.c standard
 osfmk/kdp/ml/arm/kdp_machdep.c optional        mach_kdp
 osfmk/kdp/ml/arm/kdp_vm.c      optional        mach_kdp
 
-
 # DUMMIES TO FORCE GENERATION OF .h FILES
 osfmk/OPTIONS/ln               optional ln
 osfmk/OPTIONS/eisa             optional eisa
index e5234f0d9972035a41fa2fad17fda62160f25635..61e470322701eae6926688c5a8e0cbf0b894a37b 100644 (file)
@@ -65,7 +65,6 @@ osfmk/arm/commpage/commpage.c standard
 osfmk/kdp/ml/arm/kdp_machdep.c optional        mach_kdp
 osfmk/kdp/ml/arm/kdp_vm.c      optional        mach_kdp
 
-
 # DUMMIES TO FORCE GENERATION OF .h FILES
 osfmk/OPTIONS/ln               optional ln
 osfmk/OPTIONS/eisa             optional eisa
index 7fe01580c164fe4af93b38d71808f4aa8a694e3e..e663bd3eee8821a819e63125ce95844c85cb3f87 100644 (file)
@@ -97,10 +97,6 @@ osfmk/kdp/ml/i386/kdp_x86_common.c   optional        mach_kdp
 osfmk/i386/hibernate_i386.c            optional hibernation
 osfmk/i386/hibernate_restore.c         optional hibernation
 
-osfmk/chud/i386/chud_osfmk_callback_i386.c     standard
-osfmk/chud/i386/chud_cpu_i386.c                        standard
-osfmk/chud/i386/chud_thread_i386.c             standard
-
 osfmk/i386/ucode.c                             standard
 
 osfmk/i386/vmx/vmx_cpu.c                       optional config_vmx
index d3d43107b9b4c5f73162d1256f0c8639c737ad25..59ab0759252d14725a1ac00b5305823af477bd45 100644 (file)
@@ -100,8 +100,6 @@ extern kern_return_t task_duplicate_map_and_threads(
                        int *size,
                        int *num_udata);
 
-extern boolean_t task_allowed_vm_map_fork(task_t task __unused);
-
 extern kern_return_t task_enqueue_exception_with_corpse(
        task_t task,
        exception_type_t etype,
index 4948c08a4fb25fac7dc48012f7a50fa504595863..0d3b24380e1f95066e3c85b41572e94fb5621e79 100644 (file)
@@ -808,6 +808,12 @@ routine io_registry_entry_from_path_ool(
 
 #endif
 
+routine io_device_tree_entry_exists_with_name(
+           master_port         : mach_port_t;
+       in  name                : io_name_t;
+       out exists              : boolean_t
+       );
+
 #endif /* IOKIT */
 
 /* vim: set ft=c : */
index d44eea33c0de74d9ca855134c03576dbd7f09890..75650da7bd18b511f094055b89c4c024ad120eb3 100644 (file)
 #if defined(__arm__) || defined(__arm64__)
 #include <arm/pmap.h>
 #endif
-#include <IOKit/IOTypes.h>
+#include <IOKit/IOKitServer.h>
 
 #define EXTERN
 #define MIGEXTERN
 
-/*
- * Functions in iokit:IOUserClient.cpp
- */
-
-extern void iokit_add_reference( io_object_t obj );
-extern void iokit_add_connect_reference( io_object_t obj );
-
-extern ipc_port_t iokit_port_for_object( io_object_t obj,
-                       ipc_kobject_type_t type );
-
-extern kern_return_t iokit_client_died( io_object_t obj,
-                        ipc_port_t port, ipc_kobject_type_t type, mach_port_mscount_t * mscount );
-
-extern kern_return_t
-iokit_client_memory_for_type(
-       io_object_t     connect,
-       unsigned int    type,
-       unsigned int *  flags,
-       vm_address_t *  address,
-       vm_size_t    *  size );
-
-
-extern ppnum_t IOGetLastPageNumber(void);
-
-/*
- * Functions imported by iokit:IOUserClient.cpp
- */
-
-extern ipc_port_t iokit_alloc_object_port( io_object_t obj,
-                       ipc_kobject_type_t type );
-
-extern kern_return_t iokit_destroy_object_port( ipc_port_t port );
-
-extern mach_port_name_t iokit_make_send_right( task_t task,
-                               io_object_t obj, ipc_kobject_type_t type );
-
-extern kern_return_t iokit_mod_send_right( task_t task, mach_port_name_t name, mach_port_delta_t delta );
-
-extern io_object_t iokit_lookup_connect_ref(io_object_t clientRef, ipc_space_t task);
-
-extern io_object_t iokit_lookup_connect_ref_current_task(io_object_t clientRef);
-
-extern void iokit_retain_port( ipc_port_t port );
-extern void iokit_release_port( ipc_port_t port );
-extern void iokit_release_port_send( ipc_port_t port );
-
-extern void iokit_lock_port(ipc_port_t port);
-extern void iokit_unlock_port(ipc_port_t port);
-
-extern kern_return_t iokit_switch_object_port( ipc_port_t port, io_object_t obj, ipc_kobject_type_t type );
-
-/*
- * Functions imported by iokit:IOMemoryDescriptor.cpp
- */
-
-extern kern_return_t IOMapPages(vm_map_t map, mach_vm_address_t va, mach_vm_address_t pa,
-                                 mach_vm_size_t length, unsigned int mapFlags);
-
-extern kern_return_t IOUnmapPages(vm_map_t map, mach_vm_address_t va, mach_vm_size_t length);
-
-extern kern_return_t IOProtectCacheMode(vm_map_t map, mach_vm_address_t va,
-                                       mach_vm_size_t length, unsigned int options);
-
-extern unsigned int IODefaultCacheBits(addr64_t pa);
-
 /*
  * Lookup a device by its port.
  * Doesn't consume the naked send right; produces a device reference.
  */
-MIGEXTERN io_object_t
-iokit_lookup_object_port(
-       ipc_port_t      port)
+static io_object_t
+iokit_lookup_io_object(ipc_port_t port, ipc_kobject_type_t type)
 {
        io_object_t     obj;
 
@@ -150,9 +84,9 @@ iokit_lookup_object_port(
            return (NULL);
 
        iokit_lock_port(port);
-       if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_OBJECT)) {
+       if (ip_active(port) && (ip_kotype(port) == type)) {
            obj = (io_object_t) port->ip_kobject;
-           iokit_add_reference( obj );
+           iokit_add_reference( obj, type );
        }
        else
            obj = NULL;
@@ -163,37 +97,29 @@ iokit_lookup_object_port(
 }
 
 MIGEXTERN io_object_t
-iokit_lookup_connect_port(
+iokit_lookup_object_port(
        ipc_port_t      port)
 {
-       io_object_t     obj;
-
-       if (!IP_VALID(port))
-           return (NULL);
-
-       iokit_lock_port(port);
-       if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_CONNECT)) {
-           obj = (io_object_t) port->ip_kobject;
-           iokit_add_connect_reference( obj );
-       }
-       else
-           obj = NULL;
-
-       iokit_unlock_port(port);
+    return (iokit_lookup_io_object(port, IKOT_IOKIT_OBJECT));
+}
 
-       return( obj );
+MIGEXTERN io_object_t
+iokit_lookup_connect_port(
+       ipc_port_t      port)
+{
+    return (iokit_lookup_io_object(port, IKOT_IOKIT_CONNECT));
 }
 
-EXTERN io_object_t
-iokit_lookup_connect_ref(io_object_t connectRef, ipc_space_t space)
+static io_object_t
+iokit_lookup_object_in_space_with_port_name(mach_port_name_t name, ipc_kobject_type_t type, ipc_space_t space)
 {
        io_object_t obj = NULL;
 
-       if (connectRef && MACH_PORT_VALID(CAST_MACH_PORT_TO_NAME(connectRef))) {
+       if (name && MACH_PORT_VALID(name)) {
                ipc_port_t port;
                kern_return_t kr;
 
-               kr = ipc_object_translate(space, CAST_MACH_PORT_TO_NAME(connectRef), MACH_PORT_RIGHT_SEND, (ipc_object_t *)&port);
+               kr = ipc_object_translate(space, name, MACH_PORT_RIGHT_SEND, (ipc_object_t *)&port);
 
                if (kr == KERN_SUCCESS) {
                        assert(IP_VALID(port));
@@ -202,9 +128,9 @@ iokit_lookup_connect_ref(io_object_t connectRef, ipc_space_t space)
                        ip_unlock(port);
 
                        iokit_lock_port(port);
-                       if (ip_active(port) && (ip_kotype(port) == IKOT_IOKIT_CONNECT)) {
+                       if (ip_active(port) && (ip_kotype(port) == type)) {
                                obj = (io_object_t) port->ip_kobject;
-                               iokit_add_connect_reference(obj);
+                               iokit_add_reference(obj, type);
                        }
                        iokit_unlock_port(port);
 
@@ -216,9 +142,15 @@ iokit_lookup_connect_ref(io_object_t connectRef, ipc_space_t space)
 }
 
 EXTERN io_object_t
-iokit_lookup_connect_ref_current_task(io_object_t connectRef)
+iokit_lookup_object_with_port_name(mach_port_name_t name, ipc_kobject_type_t type, task_t task)
 {
-       return iokit_lookup_connect_ref(connectRef, current_space());
+    return (iokit_lookup_object_in_space_with_port_name(name, type, task->itk_space));
+}
+
+EXTERN io_object_t
+iokit_lookup_connect_ref_current_task(mach_port_name_t name)
+{
+    return (iokit_lookup_object_in_space_with_port_name(name, IKOT_IOKIT_CONNECT, current_space()));
 }
 
 EXTERN void
@@ -257,9 +189,9 @@ iokit_unlock_port( __unused ipc_port_t port )
  * Get the port for a device.
  * Consumes a device reference; produces a naked send right.
  */
-MIGEXTERN ipc_port_t
-iokit_make_object_port(
-       io_object_t     obj )
+
+static ipc_port_t
+iokit_make_port_of_type(io_object_t obj, ipc_kobject_type_t type)
 {
     ipc_port_t port;
     ipc_port_t sendPort;
@@ -267,7 +199,7 @@ iokit_make_object_port(
     if( obj == NULL)
         return IP_NULL;
 
-    port = iokit_port_for_object( obj, IKOT_IOKIT_OBJECT );
+    port = iokit_port_for_object( obj, type );
     if( port) {
        sendPort = ipc_port_make_send( port);
        iokit_release_port( port );
@@ -280,25 +212,17 @@ iokit_make_object_port(
 }
 
 MIGEXTERN ipc_port_t
-iokit_make_connect_port(
+iokit_make_object_port(
        io_object_t     obj )
 {
-    ipc_port_t port;
-    ipc_port_t sendPort;
-
-    if( obj == NULL)
-        return IP_NULL;
-
-    port = iokit_port_for_object( obj, IKOT_IOKIT_CONNECT );
-    if( port) {
-       sendPort = ipc_port_make_send( port);
-       iokit_release_port( port );
-    } else
-       sendPort = IP_NULL;
-
-    iokit_remove_reference( obj );
+    return (iokit_make_port_of_type(obj, IKOT_IOKIT_OBJECT));
+}
 
-    return( sendPort);
+MIGEXTERN ipc_port_t
+iokit_make_connect_port(
+       io_object_t     obj )
+{
+    return (iokit_make_port_of_type(obj, IKOT_IOKIT_CONNECT));
 }
 
 int gIOKitPortCount;
@@ -317,7 +241,6 @@ iokit_alloc_object_port( io_object_t obj, ipc_kobject_type_t type )
             continue;
 
         /* set kobject & type */
-//     iokit_add_reference( obj );
        ipc_kobject_set( port, (ipc_kobject_t) obj, type);
 
         /* Request no-senders notifications on the port. */
@@ -389,8 +312,6 @@ iokit_make_send_right( task_t task, io_object_t obj, ipc_kobject_type_t type )
     else if ( sendPort == IP_DEAD)
        name = MACH_PORT_DEAD;
 
-    iokit_remove_reference( obj );
-
     return( name );
 }
 
@@ -423,8 +344,9 @@ iokit_no_senders( mach_no_senders_notification_t * notification )
             obj = (io_object_t) port->ip_kobject;
            type = ip_kotype( port );
             if( (IKOT_IOKIT_OBJECT  == type)
-            || (IKOT_IOKIT_CONNECT == type))
-                iokit_add_reference( obj );
+            || (IKOT_IOKIT_CONNECT == type)
+            || (IKOT_IOKIT_IDENT   == type))
+                iokit_add_reference( obj, IKOT_IOKIT_OBJECT );
             else
                 obj = NULL;
        }
index 10b4c4c3ff085657d18ac8b8fb8a39cf9fb072cd..614b310eb57f124ee1a614df97862e8141cd7520 100644 (file)
@@ -905,11 +905,42 @@ RecordPanicStackshot()
                        }
 
                        kdp_snapshot_preflight(-1, (void *) stackshot_begin_loc, bytes_remaining,
-                                       (STACKSHOT_KCDATA_FORMAT | STACKSHOT_NO_IO_STATS | STACKSHOT_SAVE_KEXT_LOADINFO | 
-                                        STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY | STACKSHOT_FROM_PANIC | STACKSHOT_THREAD_WAITINFO), &kc_panic_data, 0);
+                                                                       (STACKSHOT_SAVE_KEXT_LOADINFO | STACKSHOT_SAVE_LOADINFO | STACKSHOT_KCDATA_FORMAT |
+                                                                       STACKSHOT_ENABLE_BT_FAULTING | STACKSHOT_ENABLE_UUID_FAULTING | STACKSHOT_FROM_PANIC |
+                                                                       STACKSHOT_NO_IO_STATS | STACKSHOT_THREAD_WAITINFO), &kc_panic_data, 0);
                        err = do_stackshot(NULL);
                        bytes_traced = (int) kdp_stack_snapshot_bytes_traced();
-                       if (bytes_traced > 0 && !err) {
+                       bytes_used = (int) kcdata_memory_get_used_bytes(&kc_panic_data);
+
+                       if ((err != KERN_SUCCESS) && (bytes_used > 0)) {
+                               /*
+                                * We ran out of space while trying to capture a stackshot, try again without user frames.
+                                * It's not safe to log from here, but append a flag to the panic flags.
+                                */
+                               panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_STACKSHOT_KERNEL_ONLY;
+                               panic_stackshot_reset_state();
+
+                               /* Erase the stackshot data (this region is pre-populated with the NULL character) */
+                               memset(stackshot_begin_loc, '\0', bytes_used);
+
+                               err = kcdata_memory_static_init(&kc_panic_data, (mach_vm_address_t)stackshot_begin_loc,
+                                       KCDATA_BUFFER_BEGIN_STACKSHOT, bytes_remaining, KCFLAG_USE_MEMCOPY);
+                               if (err != KERN_SUCCESS) {
+                                       panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_ERROR;
+                                       panic_info->mph_other_log_offset = PE_get_offset_into_panic_region(debug_buf_ptr);
+                                       kdb_printf("Failed to re-initialize kcdata buffer for kernel only in-memory panic stackshot, skipping ...\n");
+                                       return;
+                               }
+
+                               kdp_snapshot_preflight(-1, (void *) stackshot_begin_loc, bytes_remaining, (STACKSHOT_KCDATA_FORMAT |
+                                               STACKSHOT_NO_IO_STATS | STACKSHOT_SAVE_KEXT_LOADINFO | STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY |
+                                               STACKSHOT_FROM_PANIC | STACKSHOT_THREAD_WAITINFO), &kc_panic_data, 0);
+                               err = do_stackshot(NULL);
+                               bytes_traced = (int) kdp_stack_snapshot_bytes_traced();
+                               bytes_used = (int) kcdata_memory_get_used_bytes(&kc_panic_data);
+                       }
+
+                       if (err == KERN_SUCCESS) {
                                debug_buf_ptr += bytes_traced;
                                panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_STACKSHOT_SUCCEEDED;
                                panic_info->mph_stackshot_offset = PE_get_offset_into_panic_region(stackshot_begin_loc);
@@ -918,10 +949,9 @@ RecordPanicStackshot()
                                panic_info->mph_other_log_offset = PE_get_offset_into_panic_region(debug_buf_ptr);
                                kdb_printf("\n** In Memory Panic Stackshot Succeeded ** Bytes Traced %d **\n", bytes_traced);
                        } else {
-                               bytes_used = (int) kcdata_memory_get_used_bytes(&kc_panic_data);
                                if (bytes_used > 0) {
-                                       /* Zero out the stackshot data */
-                                       bzero(stackshot_begin_loc, bytes_used);
+                                       /* Erase the stackshot data (this region is pre-populated with the NULL character) */
+                                       memset(stackshot_begin_loc, '\0', bytes_used);
                                        panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_INCOMPLETE;
 
                                        panic_info->mph_other_log_offset = PE_get_offset_into_panic_region(debug_buf_ptr);
@@ -937,7 +967,7 @@ RecordPanicStackshot()
                }
 #if DEVELOPMENT || DEBUG
                if (panic_stackshot_buf != 0) {
-                       // We're going to try to take another stackshot, reset the state.
+                       /* We're going to try to take another stackshot, reset the state. */
                        panic_stackshot_reset_state();
                }
 #endif /* DEVELOPMENT || DEBUG */
index 8d4ac80400d5bcf09e52ef0d4e9f52d16931e806..927e9400561a65f7e0888cf3dc9dc86098f25857 100644 (file)
@@ -164,7 +164,8 @@ acpi_hibernate(void *refcon)
 extern void                    slave_pstart(void);
 extern void                    hibernate_rebuild_vm_structs(void);
 
-extern unsigned int            wake_nkdbufs;
+extern unsigned int wake_nkdbufs;
+extern unsigned int trace_wrap;
 
 void
 acpi_sleep_kernel(acpi_sleep_callback func, void *refcon)
@@ -332,7 +333,7 @@ acpi_sleep_kernel(acpi_sleep_callback func, void *refcon)
        if (kdebug_enable == 0) {
                if (wake_nkdbufs) {
                        start = mach_absolute_time();
-                       kdebug_trace_start(wake_nkdbufs, NULL, TRUE);
+                       kdebug_trace_start(wake_nkdbufs, NULL, trace_wrap != 0, TRUE);
                        elapsed_trace_start += mach_absolute_time() - start;
                }
        }
@@ -460,7 +461,7 @@ acpi_idle_kernel(acpi_sleep_callback func, void *refcon)
        if (kdebug_enable == 0) {
                if (wake_nkdbufs) {
                        __kdebug_only uint64_t start = mach_absolute_time();
-                       kdebug_trace_start(wake_nkdbufs, NULL, TRUE);
+                       kdebug_trace_start(wake_nkdbufs, NULL, trace_wrap != 0, TRUE);
                        KDBG(IOKDBG_CODE(DBG_HIBERNATE, 15), start);
                }
        }
index 9dd47783c5d255273ab22aabcf5024df9114bb39..b855d1c6611ad9366ea04aa30b678b767a4ce3f8 100644 (file)
@@ -728,7 +728,6 @@ find_user_regs(thread_t thread)
 #if CONFIG_DTRACE
 /*
  * DTrace would like to have a peek at the kernel interrupt state, if available.
- * Based on osfmk/chud/i386/chud_thread_i386.c:chudxnu_thread_get_state(), which see.
  */
 x86_saved_state_t *find_kern_regs(thread_t);
 
index 618389fd9d3bd8c9bbb6d3bd985e31623b3f242c..ff08d74937aa32cab85d7097f1aeba0df4500661 100644 (file)
@@ -177,22 +177,22 @@ typedef struct cpu_data
        };
        volatile task_map_t     cpu_task_map;
        volatile addr64_t       cpu_task_cr3;
-       volatile addr64_t       cpu_ucr3;
        addr64_t                cpu_kernel_cr3;
+       volatile addr64_t       cpu_ucr3;
        boolean_t               cpu_pagezero_mapped;
        cpu_uber_t              cpu_uber;
-       /* Double-mapped per-CPU exception stack address */
+/* Double-mapped per-CPU exception stack address */
        uintptr_t               cd_estack;
-       /* Address of shadowed, partially mirrored CPU data structures located
       * in the double mapped PML4
       */
+/* Address of shadowed, partially mirrored CPU data structures located
+ * in the double mapped PML4
+ */
        void                    *cd_shadow;
        struct processor        *cpu_processor;
 #if NCOPY_WINDOWS > 0
        struct cpu_pmap         *cpu_pmap;
 #endif
-       struct cpu_desc_table   *cpu_desc_tablep;
        struct real_descriptor  *cpu_ldtp;
+       struct cpu_desc_table   *cpu_desc_tablep;
        cpu_desc_index_t        cpu_desc_index;
        int                     cpu_ldt;
 #if NCOPY_WINDOWS > 0
@@ -279,7 +279,6 @@ typedef struct cpu_data
        int                     cpu_plri;
        plrecord_t              plrecords[MAX_PREEMPTION_RECORDS];
 #endif
-       void                    *cpu_chud;
        void                    *cpu_console_buf;
        struct x86_lcpu         lcpu;
        int                     cpu_phys_number;        /* Physical CPU */
@@ -611,6 +610,11 @@ cpu_datap(int cpu) {
        return cpu_data_ptr[cpu];
 }
 
+static inline int
+cpu_is_running(int cpu) {
+       return ((cpu_datap(cpu) != NULL) && (cpu_datap(cpu)->cpu_running));
+}
+
 #ifdef MACH_KERNEL_PRIVATE
 static inline cpu_data_t *
 cpu_shadowp(int cpu) {
index 5447514d8da3c990b5d9e6006b5d35c65e3a1684..92f34b8fdf2cf4e2353e2dda7cdbcbf528880ea4 100644 (file)
@@ -1019,20 +1019,15 @@ x86_validate_topology(void)
        debug_topology_print();
 
     /*
-     * XXX
-     *
-     * Right now this only works if the number of CPUs started is the total
-     * number of CPUs.  However, when specifying cpus=n the topology is only
-     * partially constructed and the checks below will fail.
-     *
-     * We should *always* build the complete topology and only start the CPUs
-     * indicated by cpus=n.  Until that happens, this code will not check the
-     * topology if the number of cpus defined is < that described the the
-     * topology parameters.
+     * Called after processors are registered but before non-boot processors
+     * are started:
+     *  - real_ncpus: number of registered processors driven from MADT
+     *  - max_ncpus:  max number of processors that will be started 
      */
     nCPUs = topoParms.nPackages * topoParms.nLThreadsPerPackage;
-    if (nCPUs > real_ncpus)
-       return;
+    if (nCPUs != real_ncpus)
+       panic("x86_validate_topology() %d threads but %d registered from MADT",
+             nCPUs, real_ncpus);
 
     pkg = x86_pkgs;
     while (pkg != NULL) {
index e079e6e38ff011912ec22a44908b28eabd777367..a4a460893cd2ad153ff3a0781d77bc0a9aeb95b2 100644 (file)
@@ -37,6 +37,7 @@
 #include <i386/cpu_data.h>
 #include <i386/lapic.h>
 #include <i386/machine_routines.h>
+#include <stddef.h>
 
 __private_extern__ void qsort(
     void * array,
@@ -64,15 +65,14 @@ static void cpu_shadow_sort(int ncpus) {
 }
 
 /*
- * cpu_topology_sort() is called after all processors have been registered
- * but before any non-boot processor id started.
- * We establish canonical logical processor numbering - logical cpus must be
- * contiguous, zero-based and assigned in physical (local apic id) order.
- * This step is required because the discovery/registration order is
- * non-deterministic - cores are registered in differing orders over boots.
- * Enforcing canonical numbering simplifies identification
- * of processors - in particular, for stopping/starting from CHUD.
- */ 
+ * cpu_topology_sort() is called after all processors have been registered but
+ * before any non-boot processor id started.  We establish canonical logical
+ * processor numbering - logical cpus must be contiguous, zero-based and
+ * assigned in physical (local apic id) order.  This step is required because
+ * the discovery/registration order is non-deterministic - cores are registered
+ * in differing orders over boots.  Enforcing canonical numbering simplifies
+ * identification of processors.
+ */
 void
 cpu_topology_sort(int ncpus)
 {
index 2b2ff9695a1b7761306154eedd8ff7f96edfbc0f..039584749b070f6c7c6d286f792fb484cef84892 100644 (file)
@@ -418,7 +418,7 @@ uint32_t spinlock_timeout_NMI(uintptr_t thread_addr) {
        uint32_t i;
 
        for (i = 0; i < real_ncpus; i++) {
-               if ((uintptr_t)cpu_data_ptr[i]->cpu_active_thread == thread_addr) {
+               if ((cpu_data_ptr[i] != NULL) && ((uintptr_t)cpu_data_ptr[i]->cpu_active_thread == thread_addr)) {
                        spinlock_owner_cpu = i;
                        if ((uint32_t) cpu_number() != i) {
                                /* Cause NMI and panic on the owner's cpu */
@@ -1362,6 +1362,7 @@ lck_rw_unlock_shared(
 {
        lck_rw_type_t   ret;
 
+       assertf(lck->lck_rw_shared_count > 0, "lck %p has shared_count=0x%x", lck, lck->lck_rw_shared_count);
        ret = lck_rw_done(lck);
 
        if (ret != LCK_RW_TYPE_SHARED)
index cfe895601547413340681861429c86375de385f2..68f9f781925480d7fbec1ce4c0cb810f77c45468 100644 (file)
@@ -413,10 +413,6 @@ register_cpu(
        if (this_cpu_datap->cpu_console_buf == NULL)
                goto failed;
 
-       this_cpu_datap->cpu_chud = chudxnu_cpu_alloc(boot_cpu);
-       if (this_cpu_datap->cpu_chud == NULL)
-               goto failed;
-
 #if KPC
        if (kpc_register_cpu(this_cpu_datap) != TRUE)
                goto failed;
@@ -452,11 +448,10 @@ failed:
 #if NCOPY_WINDOWS > 0
        pmap_cpu_free(this_cpu_datap->cpu_pmap);
 #endif
-       chudxnu_cpu_free(this_cpu_datap->cpu_chud);
        console_cpu_free(this_cpu_datap->cpu_console_buf);
 #if KPC
        kpc_unregister_cpu(this_cpu_datap);
-#endif
+#endif /* KPC */
 
        return KERN_FAILURE;
 }
index 3e57debe3db4ac1350aedb4af4753377167a91c4..178af299df29aea4c086e41d4b3ab070d7ddee03 100644 (file)
@@ -108,9 +108,6 @@ extern void dcache_incoherent_io_store64(addr64_t pa, unsigned int count);
 extern processor_t     cpu_processor_alloc(boolean_t is_boot_cpu);
 extern void            cpu_processor_free(processor_t proc);
 
-extern void            *chudxnu_cpu_alloc(boolean_t is_boot_cpu);
-extern void            chudxnu_cpu_free(void *);
-
 extern void            sysclk_gettime_interrupts_disabled(
                                mach_timespec_t *cur_time);
 
index 1c11d96015dacf27f7ff3c98e5821966ec188f8f..3b72326873570e426d4e4582ba47b5aeb13129fc 100644 (file)
@@ -77,9 +77,6 @@
 #endif
 #include <i386/acpi.h>
 
-#include <chud/chud_xnu.h>
-#include <chud/chud_xnu_private.h>
-
 #include <sys/kdebug.h>
 
 #include <console/serial_protos.h>
@@ -552,10 +549,6 @@ cpu_signal_handler(x86_saved_state_t *regs)
                        DBGLOG(cpu_handle,my_cpu,MP_TLB_FLUSH);
                        i_bit_clear(MP_TLB_FLUSH, my_word);
                        pmap_update_interrupt();
-               } else if (i_bit(MP_CHUD, my_word)) {
-                       DBGLOG(cpu_handle,my_cpu,MP_CHUD);
-                       i_bit_clear(MP_CHUD, my_word);
-                       chudxnu_cpu_signal_handler();
                } else if (i_bit(MP_CALL, my_word)) {
                        DBGLOG(cpu_handle,my_cpu,MP_CALL);
                        i_bit_clear(MP_CALL, my_word);
@@ -699,7 +692,7 @@ NMI_cpus(void)
        intrs_enabled = ml_set_interrupts_enabled(FALSE);
 
        for (cpu = 0; cpu < real_ncpus; cpu++) {
-               if (!cpu_datap(cpu)->cpu_running)
+               if (!cpu_is_running(cpu))
                        continue;
                cpu_datap(cpu)->cpu_NMI_acknowledged = FALSE;
                cpu_NMI_interrupt(cpu);
@@ -1293,7 +1286,7 @@ mp_cpus_call1(
        }
        for (cpu = 0; cpu < (cpu_t) real_ncpus; cpu++) {
                if (((cpu_to_cpumask(cpu) & cpus) == 0) ||
-                   !cpu_datap(cpu)->cpu_running)
+                   !cpu_is_running(cpu))
                        continue;
                tsc_spin_start = rdtsc64();
                if (cpu == (cpu_t) cpu_number()) {
@@ -1461,7 +1454,7 @@ mp_cpus_kick(cpumask_t cpus)
        for (cpu = 0; cpu < (cpu_t) real_ncpus; cpu++) {
                if ((cpu == (cpu_t) cpu_number())
                        || ((cpu_to_cpumask(cpu) & cpus) == 0)
-                       || (!cpu_datap(cpu)->cpu_running))
+                       || !cpu_is_running(cpu))
                {
                                continue;
                }
@@ -1619,7 +1612,7 @@ mp_kdp_enter(boolean_t proceed_on_failure)
        DBG("mp_kdp_enter() signaling other processors\n");
        if (force_immediate_debugger_NMI == FALSE) {
                for (cpu = 0; cpu < real_ncpus; cpu++) {
-                       if (cpu == my_cpu || !cpu_datap(cpu)->cpu_running)
+                       if (cpu == my_cpu || !cpu_is_running(cpu))
                                continue;
                        ncpus++;
                        i386_signal_cpu(cpu, MP_KDP, ASYNC);
@@ -1655,12 +1648,15 @@ mp_kdp_enter(boolean_t proceed_on_failure)
                        NMIPI_enable(TRUE);
                }
                if (mp_kdp_ncpus != ncpus) {
+                       cpumask_t cpus_NMI_pending = 0;
                        DBG("mp_kdp_enter() timed-out on cpu %d, NMI-ing\n", my_cpu);
                        for (cpu = 0; cpu < real_ncpus; cpu++) {
-                               if (cpu == my_cpu || !cpu_datap(cpu)->cpu_running)
+                               if (cpu == my_cpu || !cpu_is_running(cpu))
                                        continue;
-                               if (cpu_signal_pending(cpu, MP_KDP))
+                               if (cpu_signal_pending(cpu, MP_KDP)) {
+                                       cpus_NMI_pending |= cpu_to_cpumask(cpu);
                                        cpu_NMI_interrupt(cpu);
+                               }
                        }
                        /* Wait again for the same timeout */
                        tsc_timeout = rdtsc64() + (LockTimeOutTSC);
@@ -1669,13 +1665,13 @@ mp_kdp_enter(boolean_t proceed_on_failure)
                                cpu_pause();
                        }
                        if (mp_kdp_ncpus != ncpus) {
-                               panic("mp_kdp_enter() timed-out waiting after NMI");
+                               kdb_printf("mp_kdp_enter(): %llu, %lu, %u TIMED-OUT WAITING FOR NMI-ACK, PROCEEDING\n", cpus_NMI_pending, mp_kdp_ncpus, ncpus);
                        }
                }
        }
        else
                for (cpu = 0; cpu < real_ncpus; cpu++) {
-                       if (cpu == my_cpu || !cpu_datap(cpu)->cpu_running)
+                       if (cpu == my_cpu || !cpu_is_running(cpu))
                                continue;
                        cpu_NMI_interrupt(cpu);
                }
@@ -2024,7 +2020,7 @@ mp_interrupt_watchdog(void)
             cpu < (cpu_t) real_ncpus && !machine_timeout_suspended();
             cpu++) {
                if ((cpu == (cpu_t) cpu_number()) ||
-                   (!cpu_datap(cpu)->cpu_running))
+                   (!cpu_is_running(cpu)))
                        continue;
                cpu_int_event_time = cpu_datap(cpu)->cpu_int_event_time;
                if (cpu_int_event_time == 0)
index 59c661e7aa71abdf7fd4f4de46cbd302601fb717..6fd14ed44a0cec09731d8a1c79eabd0038014471 100644 (file)
@@ -41,7 +41,6 @@ typedef enum {
        MP_AST,
        MP_IDLE,
        MP_UNIDLE,
-       MP_CHUD,
        MP_CALL,
        MP_CALL_PM,
        MP_LAST
@@ -55,7 +54,6 @@ const char *mp_event_name[] = {       \
        "MP_AST",               \
        "MP_IDLE",              \
        "MP_UNIDLE",            \
-       "MP_CHUD",              \
        "MP_CALL",              \
        "MP_CALL_PM",           \
        "MP_LAST"               \
index 5fb9112ea51416f0dadb13a39bcbe4782a9e2a1f..9a2ca43901462d59ef4e8f2978ae1d2fb245d5b2 100644 (file)
@@ -270,33 +270,32 @@ debug_state_is_valid64(x86_debug_state64_t *ds)
 static kern_return_t
 set_debug_state32(thread_t thread, x86_debug_state32_t *ds)
 {
-       x86_debug_state32_t *ids;
+       x86_debug_state32_t *new_ids;
        pcb_t pcb;
 
        pcb = THREAD_TO_PCB(thread);
-       ids = pcb->ids;
 
        if (debug_state_is_valid32(ds) != TRUE) {
                return KERN_INVALID_ARGUMENT;
        }
 
-       if (ids == NULL) {
-               ids = zalloc(ids_zone);
-               bzero(ids, sizeof *ids);
+       if (pcb->ids == NULL) {
+               new_ids = zalloc(ids_zone);
+               bzero(new_ids, sizeof *new_ids);
 
                simple_lock(&pcb->lock);
                /* make sure it wasn't already alloc()'d elsewhere */
                if (pcb->ids == NULL) {
-                       pcb->ids = ids;
+                       pcb->ids = new_ids;
                        simple_unlock(&pcb->lock);
                } else {
                        simple_unlock(&pcb->lock);
-                       zfree(ids_zone, ids);
+                       zfree(ids_zone, new_ids);
                }
        }
 
 
-       copy_debug_state32(ds, ids, FALSE);
+       copy_debug_state32(ds, pcb->ids, FALSE);
 
        return (KERN_SUCCESS);
 }
@@ -304,19 +303,18 @@ set_debug_state32(thread_t thread, x86_debug_state32_t *ds)
 static kern_return_t
 set_debug_state64(thread_t thread, x86_debug_state64_t *ds)
 {
-       x86_debug_state64_t *ids;
+       x86_debug_state64_t *new_ids;
        pcb_t pcb;
 
        pcb = THREAD_TO_PCB(thread);
-       ids = pcb->ids;
 
        if (debug_state_is_valid64(ds) != TRUE) {
                return KERN_INVALID_ARGUMENT;
        }
 
-       if (ids == NULL) {
-               ids = zalloc(ids_zone);
-               bzero(ids, sizeof *ids);
+       if (pcb->ids == NULL) {
+               new_ids = zalloc(ids_zone);
+               bzero(new_ids, sizeof *new_ids);
 
 #if HYPERVISOR
                if (thread->hv_thread_target) {
@@ -328,15 +326,15 @@ set_debug_state64(thread_t thread, x86_debug_state64_t *ds)
                simple_lock(&pcb->lock);
                /* make sure it wasn't already alloc()'d elsewhere */
                if (pcb->ids == NULL) {
-                       pcb->ids = ids;
+                       pcb->ids = new_ids;
                        simple_unlock(&pcb->lock);
                } else {
                        simple_unlock(&pcb->lock);
-                       zfree(ids_zone, ids);
+                       zfree(ids_zone, new_ids);
                }
        }
 
-       copy_debug_state64(ds, ids, FALSE);
+       copy_debug_state64(ds, pcb->ids, FALSE);
 
        return (KERN_SUCCESS);
 }
index c9be4ab8b93ce0b61359f550a4dc0c37dd6c2908..de55ad8dd6ed009cecde714262889ce35f1c29d8 100644 (file)
@@ -811,6 +811,7 @@ machine_work_interval_notify(__unused thread_t thread,
 {
 }
 
+
 void machine_switch_perfcontrol_context(__unused perfcontrol_event event,
                                        __unused uint64_t timestamp,
                                        __unused uint32_t flags,
index 9a380be1edaeffdb74aa8577b01340d3983fd362..dba69a6e742ae828f223b408b5c383f5a313afb3 100644 (file)
@@ -54,7 +54,7 @@
 #define NANOTIME                                                              \
        movq    %gs:CPU_NANOTIME,%rdi                                        ; \
        PAL_RTC_NANOTIME_READ_FAST()
-/* TODO nobarrier */
+
 /*
  * Add 64-bit delta in register reg to timer pointed to by register treg.
  */
index bb1f9a17e4eb3ab14290e68c948ec2fdb1406e94..d0ac3be95c1d1567b88149ac566615e2ed9a34bb 100644 (file)
@@ -119,8 +119,6 @@ static void user_page_fault_continue(kern_return_t kret);
 static void panic_trap(x86_saved_state64_t *saved_state, uint32_t pl, kern_return_t fault_result);
 static void set_recovery_ip(x86_saved_state64_t *saved_state, vm_offset_t ip);
 
-volatile perfCallback perfTrapHook = NULL; /* Pointer to CHUD trap hook routine */
-
 #if CONFIG_DTRACE
 /* See <rdar://problem/4613924> */
 perfCallback tempDTraceTrapHook = NULL; /* Pointer to DTrace fbt trap hook routine */
@@ -498,7 +496,6 @@ kernel_trap(
        kern_return_t           result = KERN_FAILURE;
        kern_return_t           fault_result = KERN_SUCCESS;
        thread_t                thread;
-       ast_t                   *myast;
        boolean_t               intr;
        vm_prot_t               prot;
         struct recovery                *rp;
@@ -524,18 +521,8 @@ kernel_trap(
        intr  = (saved_state->isf.rflags & EFL_IF) != 0;        /* state of ints at trap */
        kern_ip = (vm_offset_t)saved_state->isf.rip;
 
-       myast = ast_pending();
-
        is_user = (vaddr < VM_MAX_USER_PAGE_ADDRESS);
 
-       perfASTCallback astfn = perfASTHook;
-       if (__improbable(astfn != NULL)) {
-               if (*myast & AST_CHUD_ALL)
-                       astfn(AST_CHUD_ALL, myast);
-       } else
-               *myast &= ~AST_CHUD_ALL;
-
-
 #if CONFIG_DTRACE
        /*
         * Is there a DTrace hook?
@@ -885,7 +872,6 @@ user_trap(
        user_addr_t             vaddr;
        vm_prot_t               prot;
        thread_t                thread = current_thread();
-       ast_t                   *myast;
        kern_return_t           kret;
        user_addr_t             rip;
        unsigned long           dr6 = 0; /* 32 bit for i386, 64 bit for x86_64 */
@@ -939,21 +925,6 @@ user_trap(
        subcode = 0;
        exc = 0;
 
-       perfASTCallback astfn = perfASTHook;
-       if (__improbable(astfn != NULL)) {
-               myast = ast_pending();
-               if (*myast & AST_CHUD_ALL) {
-                       astfn(AST_CHUD_ALL, myast);
-               }
-       }
-
-       /* Is there a hook? */
-       perfCallback fn = perfTrapHook;
-       if (__improbable(fn != NULL)) {
-               if (fn(type, saved_state, 0, 0) == KERN_SUCCESS)
-                       return; /* If it succeeds, we are done... */
-       }
-
 #if CONFIG_DTRACE
        /*
         * DTrace does not consume all user traps, only INT_3's for now.
index 33676cf7581f07475a0427eccb59a2c15b9505c5..6966aeca2c008e0d7fa1626457a67ef5717655b7 100644 (file)
@@ -141,12 +141,6 @@ typedef kern_return_t (*perfCallback)(
                                uintptr_t               *lo_spp,
                                      int);
 
-typedef kern_return_t (*perfASTCallback)(ast_t reasons, ast_t *myast);
-
-extern volatile perfCallback perfTrapHook;
-extern volatile perfASTCallback perfASTHook;
-extern volatile perfCallback perfIntHook;
-
 extern void            panic_i386_backtrace(void *, int, const char *, boolean_t, x86_saved_state_t *);
 extern void    print_one_backtrace(pmap_t pmap, vm_offset_t topfp, const char *cur_marker, boolean_t is_64_bit);
 extern void    print_thread_num_that_crashed(task_t task);
index e5445a290db53c702c70b7cc776f532674f5f8ca..736fe824c8d75eb4c70a54196fa9c3af3b1f4ff8 100644 (file)
@@ -720,7 +720,7 @@ void ipc_kmsg_trace_send(ipc_kmsg_t kmsg,
        case IKOT_MASTER_DEVICE:
        case IKOT_IOKIT_CONNECT:
        case IKOT_IOKIT_OBJECT:
-       case IKOT_IOKIT_SPARE:
+       case IKOT_IOKIT_IDENT:
                msg_flags |= KMSG_TRACE_FLAG_IOKIT;
                break;
        default:
index ac71c806165f94d3dfd6e03c215b1f888a36fec6..c3ea1037c9f42657fd34e5c99fb0142e51f5071a 100644 (file)
@@ -862,6 +862,13 @@ pmap_traverse_present_mappings(pmap_t __unused pmap,
        /* send previous run */
        ret = callback(vcurstart, vcur, context);
     }
+
+#if KASAN
+    if (ret == KERN_SUCCESS) {
+       ret = kasan_traverse_mappings(callback, context);
+    }
+#endif
+
     return (ret);
 }
 
index 244ac7d07cb9fddfa1a104acf24f7567125efac3..8f5403edf86bf1cdb9cd05e6cccf5a8dde206d6d 100644 (file)
@@ -100,9 +100,7 @@ kern_collectth_state(thread_t thread, void *buffer, uint64_t size, void ** iter)
 
                /* Locate and obtain the non-volatile register context
                 * for this kernel thread. This should ideally be
-                * encapsulated in machine_thread_get_kern_state()
-                * but that routine appears to have been co-opted
-                * by CHUD to obtain pre-interrupt state.
+                * encapsulated in machine_thread_get_kern_state().
                 */
                if (thread_flavor_array[i].flavor == x86_THREAD_STATE64) {
                        x86_thread_state64_t *tstate = (x86_thread_state64_t *) ((uintptr_t)buffer + hoffset);
index e0480272f34ee0e29665094c76bfc72756b575f8..dcde0c50eec202517bec8a7cae367df0bf6605ce 100644 (file)
@@ -1,3 +1,4 @@
+
 export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
 export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
 export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
@@ -79,7 +80,7 @@ INSTALL_KF_MI_LCL_LIST = ${DATAFILES} ${PRIVATE_DATAFILES} ${EXPORT_FILES} ${PRI
 
 INSTALL_MI_DIR = kern
 
-EXPORT_MI_LIST = ${DATAFILES} ${PRIVATE_DATAFILES} ${EXPORT_FILES}
+EXPORT_MI_LIST = ${DATAFILES} ${PRIVATE_DATAFILES} ${EXPORT_FILES} ipc_kobject.h
 
 EXPORT_MI_DIR = kern
 
index 4710f64ed12639d51ce77dfec957b281d797a5c8..d41821e2d3bb85f19d804198cbca24e07df0a154 100644 (file)
@@ -118,8 +118,7 @@ typedef uint32_t ast_t;
 #define AST_BSD                        0x80
 #define AST_KPERF              0x100   /* kernel profiling */
 #define        AST_MACF                0x200   /* MACF user ret pending */
-#define AST_CHUD               0x400 
-#define AST_CHUD_URGENT                0x800
+/* 0x400, 0x800 unused */
 #define AST_GUARD              0x1000
 #define AST_TELEMETRY_USER     0x2000  /* telemetry sample requested on interrupt from userspace */
 #define AST_TELEMETRY_KERNEL   0x4000  /* telemetry sample requested on interrupt from kernel */
@@ -135,7 +134,6 @@ typedef uint32_t ast_t;
 #define AST_SCHEDULING (AST_PREEMPTION | AST_YIELD | AST_HANDOFF)
 #define AST_PREEMPTION (AST_PREEMPT | AST_QUANTUM | AST_URGENT)
 
-#define AST_CHUD_ALL   (AST_CHUD_URGENT|AST_CHUD)
 #define AST_TELEMETRY_ALL      (AST_TELEMETRY_USER | AST_TELEMETRY_KERNEL | AST_TELEMETRY_IO)
 
 /* Per-thread ASTs follow the thread at context-switch time. */
index 7196cc5c649699d696fd5673fcf1ca8d895c8972..f70820520a4b8064a2b4ce4c950102a12cb53037 100644 (file)
@@ -1032,20 +1032,20 @@ fill_task_qos_rusage(task_t task, rusage_info_current *ri)
        assert(task != TASK_NULL);
        task_lock(task);
 
-       /* Rollup Qos time of all the threads to task */
+       /* Rollup QoS time of all the threads to task */
        queue_iterate(&task->threads, thread, thread_t, task_threads) {
                if (thread->options & TH_OPT_IDLE_THREAD)
                        continue;
 
                thread_update_qos_cpu_time(thread);
        }
-       ri->ri_cpu_time_qos_default = task->cpu_time_qos_stats.cpu_time_qos_default;
-       ri->ri_cpu_time_qos_maintenance = task->cpu_time_qos_stats.cpu_time_qos_maintenance;
-       ri->ri_cpu_time_qos_background = task->cpu_time_qos_stats.cpu_time_qos_background;
-       ri->ri_cpu_time_qos_utility = task->cpu_time_qos_stats.cpu_time_qos_utility;
-       ri->ri_cpu_time_qos_legacy = task->cpu_time_qos_stats.cpu_time_qos_legacy;
-       ri->ri_cpu_time_qos_user_initiated = task->cpu_time_qos_stats.cpu_time_qos_user_initiated;
-       ri->ri_cpu_time_qos_user_interactive = task->cpu_time_qos_stats.cpu_time_qos_user_interactive;
+       ri->ri_cpu_time_qos_default = task->cpu_time_eqos_stats.cpu_time_qos_default;
+       ri->ri_cpu_time_qos_maintenance = task->cpu_time_eqos_stats.cpu_time_qos_maintenance;
+       ri->ri_cpu_time_qos_background = task->cpu_time_eqos_stats.cpu_time_qos_background;
+       ri->ri_cpu_time_qos_utility = task->cpu_time_eqos_stats.cpu_time_qos_utility;
+       ri->ri_cpu_time_qos_legacy = task->cpu_time_eqos_stats.cpu_time_qos_legacy;
+       ri->ri_cpu_time_qos_user_initiated = task->cpu_time_eqos_stats.cpu_time_qos_user_initiated;
+       ri->ri_cpu_time_qos_user_interactive = task->cpu_time_eqos_stats.cpu_time_qos_user_interactive;
 
        task_unlock(task);
        return (0);
index 9db2789eff01e8ffba404b2b1a3dd363a53a611c..ed24958c17f84eda87e664f3ec16ce73b92f37b9 100644 (file)
@@ -167,6 +167,12 @@ static int           i_coal_resource_get_taskrole(coalition_t coal, task_t task)
 static void          i_coal_resource_iterate_tasks(coalition_t coal, void *ctx,
                                                   void (*callback)(coalition_t, void *, task_t));
 
+/*
+ * Ensure COALITION_NUM_THREAD_QOS_TYPES defined in mach/coalition.h still
+ * matches THREAD_QOS_LAST defined in mach/thread_policy.h
+ */
+static_assert(COALITION_NUM_THREAD_QOS_TYPES == THREAD_QOS_LAST);
+
 struct i_resource_coalition {
        ledger_t ledger;
        uint64_t bytesread;
@@ -178,6 +184,8 @@ struct i_resource_coalition {
        uint64_t logical_invalidated_writes;
        uint64_t logical_metadata_writes;
        uint64_t cpu_ptime;
+       uint64_t cpu_time_eqos[COALITION_NUM_THREAD_QOS_TYPES];      /* cpu time per effective QoS class */
+       uint64_t cpu_time_rqos[COALITION_NUM_THREAD_QOS_TYPES];      /* cpu time per requested QoS class */
 
        uint64_t task_count;      /* tasks that have started in this coalition */
        uint64_t dead_task_count; /* tasks that have exited in this coalition;
@@ -424,6 +432,7 @@ i_coal_resource_remove_task(coalition_t coal, task_t task)
                cr->logical_invalidated_writes += task->task_invalidated_writes;
                cr->logical_metadata_writes += task->task_metadata_writes;
                cr->cpu_ptime += task_cpu_ptime(task);
+               task_update_cpu_time_qos_stats(task, cr->cpu_time_eqos, cr->cpu_time_rqos);
        }
 
        /* remove the task from the coalition's list */
@@ -509,7 +518,10 @@ coalition_resource_usage_internal(coalition_t coal, struct coalition_resource_us
        int64_t energy_billed_to_me = 0;
        int64_t energy_billed_to_others = 0;
        uint64_t cpu_ptime = coal->r.cpu_ptime;
-
+       uint64_t cpu_time_eqos[COALITION_NUM_THREAD_QOS_TYPES];
+       memcpy(cpu_time_eqos, coal->r.cpu_time_eqos, sizeof(cpu_time_eqos));
+       uint64_t cpu_time_rqos[COALITION_NUM_THREAD_QOS_TYPES];
+       memcpy(cpu_time_rqos, coal->r.cpu_time_rqos, sizeof(cpu_time_rqos));
        /*
         * Add to that all the active tasks' ledgers. Tasks cannot deallocate
         * out from under us, since we hold the coalition lock.
@@ -537,6 +549,7 @@ coalition_resource_usage_internal(coalition_t coal, struct coalition_resource_us
                logical_invalidated_writes += task->task_invalidated_writes;
                logical_metadata_writes += task->task_metadata_writes;
                cpu_ptime += task_cpu_ptime(task);
+               task_update_cpu_time_qos_stats(task, cpu_time_eqos, cpu_time_rqos);
        }
 
        kr = ledger_get_balance(sum_ledger, task_ledgers.cpu_time_billed_to_me, (int64_t *)&cpu_time_billed_to_me);
@@ -603,7 +616,8 @@ coalition_resource_usage_internal(coalition_t coal, struct coalition_resource_us
        cru_out->logical_invalidated_writes = logical_invalidated_writes;
        cru_out->logical_metadata_writes = logical_metadata_writes;
        cru_out->cpu_ptime = cpu_ptime;
-
+       cru_out->cpu_time_eqos_len = COALITION_NUM_THREAD_QOS_TYPES;
+       memcpy(cru_out->cpu_time_eqos, cpu_time_eqos, sizeof(cru_out->cpu_time_eqos));
        ledger_dereference(sum_ledger);
        sum_ledger = LEDGER_NULL;
 
index a84f86d75bcbb44112598c6aff029358e6b5023b..313c979b52e1a8342e002ced916692bf37d8229a 100644 (file)
@@ -684,7 +684,7 @@ panic_trap_to_debugger(const char *panic_format_str, va_list *panic_args, unsign
        if (write_trace_on_panic && kdebug_enable) {
                if (get_preemption_level() == 0 && !ml_at_interrupt_context()) {
                        ml_set_interrupts_enabled(TRUE);
-                       KDBG(TRACE_PANIC);
+                       KDBG_RELEASE(TRACE_PANIC);
                        kdbg_dump_trace_to_file(KDBG_TRACE_PANIC_FILENAME);
                }
        }
index 6289eeecd3593b538c53dd0b0f17438e8e680379..860824c047187cd8a57a9f843c087a29a0ce8fdd 100644 (file)
@@ -276,10 +276,15 @@ struct embedded_panic_header {
        uint32_t eph_stackshot_len;        /* length of the panic stackshot (0 if not valid ) */
        uint32_t eph_other_log_offset;     /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */
        uint32_t eph_other_log_len;        /* length of the other log */
-       uint64_t eph_x86_power_state:8,
-                eph_x86_efi_boot_state:8,
-                eph_x86_system_state:8,
-                eph_x86_unused_bits:40;
+       union {
+               struct {
+                       uint64_t eph_x86_power_state:8,
+                                eph_x86_efi_boot_state:8,
+                                eph_x86_system_state:8,
+                                eph_x86_unused_bits:40;
+               }; // anonymous struct to group the bitfields together.
+               uint64_t eph_x86_do_not_use; /* Used for offsetof/sizeof when parsing header */
+       };
 } __attribute__((packed));
 
 #define EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_COMPLETE             0x01
@@ -324,6 +329,7 @@ struct macos_panic_header {
 #define MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_NESTED       0x80
 #define MACOS_PANIC_HEADER_FLAG_COREDUMP_COMPLETE             0x100
 #define MACOS_PANIC_HEADER_FLAG_COREDUMP_FAILED               0x200
+#define MACOS_PANIC_HEADER_FLAG_STACKSHOT_KERNEL_ONLY         0x400
 
 #endif /* __APPLE_API_UNSTABLE */
 #endif /* __APPLE_API_PRIVATE */
index 1acc81c4a3e2bdb262f90d19b02d92c75666bd42..181bb0383f9d79010260599c6bb7a3708dcb5f60 100644 (file)
@@ -700,7 +700,7 @@ ipc_kobject_notify(
 #ifdef IOKIT
                case IKOT_IOKIT_OBJECT:
                case IKOT_IOKIT_CONNECT:
-               case IKOT_IOKIT_SPARE:
+               case IKOT_IOKIT_IDENT:
                {
                 return iokit_notify(request_header);
                }
index 74c4768c06477eb1d97b3c4df8e1ea55bb0f61ad..52431b60e6f46214f25728eb5bdd6ba0a5e4721f 100644 (file)
  *     Declarations for letting a port represent a kernel object.
  */
 
+#ifdef MACH_KERNEL_PRIVATE
 #include <ipc/ipc_kmsg.h>
 #include <ipc/ipc_port.h>
+#endif /* MACH_KERNEL_PRIVATE */
 
 #ifndef        _KERN_IPC_KOBJECT_H_
 #define _KERN_IPC_KOBJECT_H_
@@ -114,7 +116,7 @@ typedef natural_t   ipc_kobject_type_t;
 #define IKOT_LOCK_SET                  24
 #define IKOT_CLOCK                             25
 #define IKOT_CLOCK_CTRL                        26
-#define IKOT_IOKIT_SPARE               27
+#define IKOT_IOKIT_IDENT               27
 #define IKOT_NAMED_ENTRY               28
 #define IKOT_IOKIT_CONNECT             29
 #define IKOT_IOKIT_OBJECT              30
@@ -138,6 +140,8 @@ typedef natural_t   ipc_kobject_type_t;
 
 #define is_ipc_kobject(ikot)   ((ikot) != IKOT_NONE)
 
+#ifdef MACH_KERNEL_PRIVATE
+
 /*
  *     Define types of kernel objects that use page lists instead
  *     of entry lists for copyin of out of line memory.
@@ -165,6 +169,8 @@ extern void         ipc_kobject_destroy(
 
 #define        null_conversion(port)   (port)
 
+#endif /* MACH_KERNEL_PRIVATE */
+
 #endif /* KERNEL_PRIVATE */
 
 #endif /* _KERN_IPC_KOBJECT_H_ */
index fa13463fe5573025040e9873d3addcce17a975d1..65e9df392e840f5bed327bf90533516c61759311 100644 (file)
@@ -67,6 +67,7 @@
 #include <zone_debug.h>
 
 #include <mach/boolean.h>
+#include <mach/sdt.h>
 #include <mach/machine/vm_types.h>
 #include <mach/vm_param.h>
 #include <kern/misc_protos.h>
@@ -128,129 +129,95 @@ KALLOC_ZINFO_SFREE(vm_size_t bytes)
 }
 
 /*
- *     All allocations of size less than kalloc_max are rounded to the
- *     next nearest sized zone.  This allocator is built on top of
- *     the zone allocator.  A zone is created for each potential size
- *     that we are willing to get in small blocks.
+ * All allocations of size less than kalloc_max are rounded to the next nearest
+ * sized zone.  This allocator is built on top of the zone allocator.  A zone
+ * is created for each potential size that we are willing to get in small
+ * blocks.
  *
- *     We assume that kalloc_max is not greater than 64K;
+ * We assume that kalloc_max is not greater than 64K;
  *
- *     Note that kalloc_max is somewhat confusingly named.
- *     It represents the first power of two for which no zone exists.
- *     kalloc_max_prerounded is the smallest allocation size, before
- *     rounding, for which no zone exists.
+ * Note that kalloc_max is somewhat confusingly named. It represents the first
+ * power of two for which no zone exists.  kalloc_max_prerounded is the
+ * smallest allocation size, before rounding, for which no zone exists.
  *
- *     Also if the allocation size is more than kalloc_kernmap_size
- *     then allocate from kernel map rather than kalloc_map.
+ * Also if the allocation size is more than kalloc_kernmap_size then allocate
+ * from kernel map rather than kalloc_map.
  */
 
-#if KALLOC_MINSIZE == 16 && KALLOC_LOG2_MINALIGN == 4
+#define KALLOC_MINALIGN (1 << KALLOC_LOG2_MINALIGN)
+#define KiB(x) (1024 * (x))
 
-#define K_ZONE_SIZES \
-       16, \
-       32, \
-       48, \
-       64, /* 2^6 */ \
-       80, \
-       96, \
-       128, /* 2^7 */ \
-       160, \
-       192, \
-       224, \
-       256, /* 2^8 */ \
-       288, \
-       368, \
-       400, \
-       512, /* 2^9 */\
-       576, \
-       768, \
-       1024, /* 2^10 */ \
-       1152, \
-       1280, \
-       1664, \
-       2048, /* 2^11 */ \
-       4096, /* 2^12 */ \
-       6144
-
-#define K_ZONE_NAMES \
-       "kalloc.16", \
-       "kalloc.32", \
-       "kalloc.48", \
-       "kalloc.64", /* 2^6 */ \
-       "kalloc.80", \
-       "kalloc.96", \
-       "kalloc.128", /* 2^7 */ \
-       "kalloc.160", \
-       "kalloc.192", \
-       "kalloc.224", \
-       "kalloc.256", /* 2^8 */\
-       "kalloc.288", \
-       "kalloc.368", \
-       "kalloc.400", \
-       "kalloc.512", /* 2^9 */ \
-       "kalloc.576", \
-       "kalloc.768", \
-       "kalloc.1024", /* 2^10 */ \
-       "kalloc.1152", \
-       "kalloc.1280", \
-       "kalloc.1664", \
-       "kalloc.2048", /* 2^11 */ \
-       "kalloc.4096", /* 2^12 */ \
-       "kalloc.6144"
+static const struct kalloc_zone_config {
+       int kzc_size;
+       const char *kzc_name;
+} k_zone_config[] = {
+#define KZC_ENTRY(SIZE) { .kzc_size = (SIZE), .kzc_name = "kalloc." #SIZE }
 
+#if KALLOC_MINSIZE == 16 && KALLOC_LOG2_MINALIGN == 4
+       /* 64-bit targets, generally */
+       KZC_ENTRY(16),
+       KZC_ENTRY(32),
+       KZC_ENTRY(48),
+       KZC_ENTRY(64),
+       KZC_ENTRY(80),
+       KZC_ENTRY(96),
+       KZC_ENTRY(128),
+       KZC_ENTRY(160),
+       KZC_ENTRY(192),
+       KZC_ENTRY(224),
+       KZC_ENTRY(256),
+       KZC_ENTRY(288),
+       KZC_ENTRY(368),
+       KZC_ENTRY(400),
+       KZC_ENTRY(512),
+       KZC_ENTRY(576),
+       KZC_ENTRY(768),
+       KZC_ENTRY(1024),
+       KZC_ENTRY(1152),
+       KZC_ENTRY(1280),
+       KZC_ENTRY(1664),
+       KZC_ENTRY(2048),
 #elif KALLOC_MINSIZE == 8 && KALLOC_LOG2_MINALIGN == 3
-
-/*
- * Tweaked for ARM (and x64) in 04/2011
- */
-
-#define K_ZONE_SIZES                   \
-/* 3 */        8,                              \
-       16,     24,                     \
-       32,     40,     48,             \
-/* 6 */        64,     72,     88,     112,    \
-       128,    192,                    \
-       256,    288,    384,    440,    \
-/* 9 */        512,    576,    768,            \
-       1024,   1152,   1536,           \
-       2048,   2128,   3072,                   \
-       4096,   6144
-
-#define K_ZONE_NAMES                   \
-/* 3 */        "kalloc.8",                     \
-       "kalloc.16",    "kalloc.24",    \
-       "kalloc.32",    "kalloc.40",    "kalloc.48",    \
-/* 6 */        "kalloc.64",    "kalloc.72",    "kalloc.88",    "kalloc.112",   \
-       "kalloc.128",   "kalloc.192",   \
-       "kalloc.256",   "kalloc.288",   "kalloc.384",   "kalloc.440",   \
-/* 9 */        "kalloc.512",   "kalloc.576",   "kalloc.768",   \
-       "kalloc.1024",  "kalloc.1152",  "kalloc.1536",  \
-       "kalloc.2048",  "kalloc.2128",  "kalloc.3072",  \
-       "kalloc.4096",  "kalloc.6144"
-
+       /* 32-bit targets, generally */
+       KZC_ENTRY(8),
+       KZC_ENTRY(16),
+       KZC_ENTRY(24),
+       KZC_ENTRY(32),
+       KZC_ENTRY(40),
+       KZC_ENTRY(48),
+       KZC_ENTRY(64),
+       KZC_ENTRY(72),
+       KZC_ENTRY(88),
+       KZC_ENTRY(112),
+       KZC_ENTRY(128),
+       KZC_ENTRY(192),
+       KZC_ENTRY(256),
+       KZC_ENTRY(288),
+       KZC_ENTRY(384),
+       KZC_ENTRY(440),
+       KZC_ENTRY(512),
+       KZC_ENTRY(576),
+       KZC_ENTRY(768),
+       KZC_ENTRY(1024),
+       KZC_ENTRY(1152),
+       KZC_ENTRY(1536),
+       KZC_ENTRY(2048),
+       KZC_ENTRY(2128),
+       KZC_ENTRY(3072),
 #else
 #error missing or invalid zone size parameters for kalloc
 #endif
 
-#define KALLOC_MINALIGN (1 << KALLOC_LOG2_MINALIGN)
-#define KiB(x) (1024 * (x))
-
-static const int k_zone_size[] = {
-       K_ZONE_SIZES,
-       KiB(8),
-       KiB(16),
-       KiB(32)
-};
-
-#define MAX_K_ZONE     (sizeof (k_zone_size) / sizeof (k_zone_size[0]))
-
-static const char *k_zone_name[MAX_K_ZONE] = {
-       K_ZONE_NAMES,
-       "kalloc.8192",
-       "kalloc.16384",
-       "kalloc.32768"
+       /* all configurations get these zones */
+       KZC_ENTRY(4096),
+       KZC_ENTRY(6144),
+       KZC_ENTRY(8192),
+       KZC_ENTRY(16384),
+       KZC_ENTRY(32768),
+#undef KZC_ENTRY
 };
 
+#define MAX_K_ZONE (int)(sizeof(k_zone_config) / sizeof(k_zone_config[0]))
 
 /*
  * Many kalloc() allocations are for small structures containing a few
@@ -316,7 +283,6 @@ kalloc_init(
        kern_return_t retval;
        vm_offset_t min;
        vm_size_t size, kalloc_map_size;
-       int i;
        vm_map_kernel_flags_t vmk_flags;
 
        /* 
@@ -348,10 +314,10 @@ kalloc_init(
        kalloc_map_max = min + kalloc_map_size - 1;
 
        /*
-        * Create zones up to a least 2 pages because small page-multiples are common
-        * allocations. Also ensure that zones up to size 8192 bytes exist. This is
-        * desirable because messages are allocated with kalloc(), and messages up
-        * through size 8192 are common.
+        * Create zones up to a least 4 pages because small page-multiples are
+        * common allocations.  Also ensure that zones up to size 16KB bytes exist.
+        * This is desirable because messages are allocated with kalloc(), and
+        * messages up through size 8192 are common.
         */
        kalloc_max = PAGE_SIZE << 2;
        if (kalloc_max < KiB(16)) {
@@ -365,12 +331,15 @@ kalloc_init(
        kalloc_largest_allocated = kalloc_kernmap_size;
 
        /*
-        * Allocate a zone for each size we are going to handle. Don't charge the
-        * caller for the allocation, as we aren't sure how the memory will be
-        * handled.
+        * Allocate a zone for each size we are going to handle.
         */
-       for (i = 0; i < (int)MAX_K_ZONE && (size = k_zone_size[i]) < kalloc_max; i++) {
-               k_zone[i] = zinit(size, size, size, k_zone_name[i]);
+       for (int i = 0; i < MAX_K_ZONE && (size = k_zone_config[i].kzc_size) < kalloc_max; i++) {
+               k_zone[i] = zinit(size, size, size, k_zone_config[i].kzc_name);
+
+               /*
+                * Don't charge the caller for the allocation, as we aren't sure how
+                * the memory will be handled.
+                */
                zone_change(k_zone[i], Z_CALLERACCT, FALSE);
 #if VM_MAX_TAG_ZONES
                if (zone_tagging_on) zone_change(k_zone[i], Z_TAGS_ENABLED, TRUE);
@@ -381,10 +350,11 @@ kalloc_init(
        /*
         * Build the Direct LookUp Table for small allocations
         */
-       for (i = 0, size = 0; i <= N_K_ZDLUT; i++, size += KALLOC_MINALIGN) {
+       size = 0;
+       for (int i = 0; i <= N_K_ZDLUT; i++, size += KALLOC_MINALIGN) {
                int zindex = 0;
 
-               while ((vm_size_t)k_zone_size[zindex] < size)
+               while ((vm_size_t)k_zone_config[zindex].kzc_size < size)
                        zindex++;
 
                if (i == N_K_ZDLUT) {
@@ -403,8 +373,8 @@ kalloc_init(
         * Useful when debugging/tweaking the array of zone sizes.
         * Cache misses probably more critical than compare-branches!
         */
-       for (i = 0; i < (int)MAX_K_ZONE; i++) {
-               vm_size_t testsize = (vm_size_t)k_zone_size[i] - 1;
+       for (int i = 0; i < MAX_K_ZONE; i++) {
+               vm_size_t testsize = (vm_size_t)k_zone_config[i].kzc_size - 1;
                int compare = 0;
                int zindex;
 
@@ -419,7 +389,7 @@ kalloc_init(
                        compare += 2;   /* 'if' (F), 'if' (T) */
 
                        zindex = k_zindex_start;
-                       while ((vm_size_t)k_zone_size[zindex] < testsize) {
+                       while ((vm_size_t)k_zone_config[zindex].kzc_size < testsize) {
                                zindex++;
                                compare++;      /* 'while' (T) */
                        }
@@ -454,18 +424,18 @@ get_zone_dlut(vm_size_t size)
        return (k_zone[zindex]);
 }
 
-/* As above, but linear search k_zone_size[] for the next zone that fits. */
+/* As above, but linear search k_zone_config[] for the next zone that fits. */
 
 static __inline zone_t
 get_zone_search(vm_size_t size, int zindex)
 {
        assert(size < kalloc_max_prerounded);
 
-       while ((vm_size_t)k_zone_size[zindex] < size)
+       while ((vm_size_t)k_zone_config[zindex].kzc_size < size)
                zindex++;
 
-       assert((unsigned)zindex < MAX_K_ZONE &&
-           (vm_size_t)k_zone_size[zindex] < kalloc_max);
+       assert(zindex < MAX_K_ZONE &&
+           (vm_size_t)k_zone_config[zindex].kzc_size < kalloc_max);
 
        return (k_zone[zindex]);
 }
@@ -574,6 +544,7 @@ kfree_addr(
 
        size = zone_element_size(addr, &z);
        if (size) {
+               DTRACE_VM3(kfree, vm_size_t, -1, vm_size_t, z->elem_size, void*, addr);
                zfree(z, addr);
                return size;
        }
@@ -600,6 +571,7 @@ kfree_addr(
                                addr, map, ret);
        }
        vm_map_unlock(map);
+       DTRACE_VM3(kfree, vm_size_t, -1, vm_size_t, size, void*, addr);
        
        kalloc_spin_lock();
        kalloc_large_total -= size;
@@ -699,6 +671,7 @@ kalloc_canblock(
 #else
                *psize = round_page(size);
 #endif
+               DTRACE_VM3(kalloc, vm_size_t, size, vm_size_t, *psize, void*, addr);
                return(addr);
        }
 #ifdef KALLOC_DEBUG
@@ -729,6 +702,7 @@ kalloc_canblock(
        *psize = z->elem_size;
 #endif
 
+       DTRACE_VM3(kalloc, vm_size_t, size, vm_size_t, *psize, void*, addr);
        return addr;
 }
 
@@ -808,6 +782,10 @@ kfree(
 
                kalloc_unlock();
 
+#if !KASAN_KALLOC
+               DTRACE_VM3(kfree, vm_size_t, size, vm_size_t, size, void*, data);
+#endif
+
                KALLOC_ZINFO_SFREE(size);
                return;
        }
@@ -819,6 +797,7 @@ kfree(
                    z, z->zone_name, (unsigned long)size);
 #endif
        assert(size <= z->elem_size);
+       DTRACE_VM3(kfree, vm_size_t, size, vm_size_t, z->elem_size, void*, data);
        zfree(z, data);
 }
 
index e358b4ec8f2dc4e8eeaacc8f7e70a05928e7a1e3..702bfacbc30ea742facb12a3ce64fba2e4ac6695 100644 (file)
@@ -456,7 +456,7 @@ struct kcdata_type_definition {
 #define STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP 0x912u /* timestamp used for the delta stackshot */
 
 #define STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT 0x940u   /* task_delta_snapshot_v2 */
-#define STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT 0x941u /* thread_delta_snapshot_v2 */
+#define STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT 0x941u /* thread_delta_snapshot_v* */
 
 #define STACKSHOT_KCTYPE_KERN_STACKLR 0x913u          /* uint32_t */
 #define STACKSHOT_KCTYPE_KERN_STACKLR64 0x914u        /* uint64_t */
@@ -704,6 +704,23 @@ struct thread_delta_snapshot_v2 {
        uint8_t   tds_io_tier;
 } __attribute__ ((packed));
 
+struct thread_delta_snapshot_v3 {
+       uint64_t  tds_thread_id;
+       uint64_t  tds_voucher_identifier;
+       uint64_t  tds_ss_flags;
+       uint64_t  tds_last_made_runnable_time;
+       uint32_t  tds_state;
+       uint32_t  tds_sched_flags;
+       int16_t   tds_base_priority;
+       int16_t   tds_sched_priority;
+       uint8_t   tds_eqos;
+       uint8_t   tds_rqos;
+       uint8_t   tds_rqos_override;
+       uint8_t   tds_io_tier;
+       uint64_t  tds_requested_policy;
+       uint64_t  tds_effective_policy;
+} __attribute__ ((packed));
+
 struct io_stats_snapshot
 {
        /*
@@ -805,13 +822,22 @@ typedef struct stackshot_thread_waitinfo {
 
 /* FIXME some of these types aren't clean (fixed width,  packed, and defined *here*) */
 
+struct crashinfo_proc_uniqidentifierinfo {
+       uint8_t                 p_uuid[16];             /* UUID of the main executable */
+       uint64_t                p_uniqueid;             /* 64 bit unique identifier for process */
+       uint64_t                p_puniqueid;            /* unique identifier for process's parent */
+       uint64_t                p_reserve2;             /* reserved for future use */
+       uint64_t                p_reserve3;             /* reserved for future use */
+       uint64_t                p_reserve4;             /* reserved for future use */
+} __attribute__((packed));
+
 #define TASK_CRASHINFO_BEGIN                KCDATA_BUFFER_BEGIN_CRASHINFO
 #define TASK_CRASHINFO_STRING_DESC          KCDATA_TYPE_STRING_DESC
 #define TASK_CRASHINFO_UINT32_DESC          KCDATA_TYPE_UINT32_DESC
 #define TASK_CRASHINFO_UINT64_DESC          KCDATA_TYPE_UINT64_DESC
 
 #define TASK_CRASHINFO_EXTMODINFO           0x801
-#define TASK_CRASHINFO_BSDINFOWITHUNIQID    0x802 /* struct proc_uniqidentifierinfo */
+#define TASK_CRASHINFO_BSDINFOWITHUNIQID    0x802 /* struct crashinfo_proc_uniqidentifierinfo */
 #define TASK_CRASHINFO_TASKDYLD_INFO        0x803
 #define TASK_CRASHINFO_UUID                 0x804
 #define TASK_CRASHINFO_PID                  0x805
index 6070cdc266c9b7f95f0898aab692e4c2d6ac99e5..97bee226c7dd956196491fae6ab3b291ef45aef3 100644 (file)
@@ -186,23 +186,24 @@ static kern_return_t kcdata_get_memory_addr_with_flavor(
                mach_vm_address_t *user_addr)
 {
        struct kcdata_item info;
-       uint32_t total_size;
-
-       if (user_addr == NULL || data == NULL) {
-               return KERN_INVALID_ARGUMENT;
-       }
 
+       uint32_t orig_size = size;
        /* make sure 16 byte aligned */
        size += kcdata_calc_padding(size);
+       uint32_t total_size  = size + sizeof(info);
+
+       if (user_addr == NULL || data == NULL || total_size + sizeof(info) < orig_size) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        bzero(&info, sizeof(info));
        info.type  = type;
        info.size = size;
        info.flags = flags;
-       total_size = size + sizeof(info);
 
        /* check available memory, including trailer size for KCDATA_TYPE_BUFFER_END */
-       if (data->kcd_length < ((data->kcd_addr_end - data->kcd_addr_begin) + total_size + sizeof(info))) {
+       if (total_size + sizeof(info) > data->kcd_length ||
+               data->kcd_length - (total_size + sizeof(info)) < data->kcd_addr_end - data->kcd_addr_begin) {
                return KERN_RESOURCE_SHORTAGE;
        }
 
index be60881383cd18c3f90a0b5728d429489e79daee..0c1e07bf17d08993c40af34716f43f82d8b5f2ec 100644 (file)
@@ -1079,6 +1079,25 @@ error_exit:
        return error;
 }
 
+#if MONOTONIC
+static kern_return_t
+kcdata_record_task_instrs_cycles(kcdata_descriptor_t kcd, task_t task)
+{
+       uint64_t instrs = 0, cycles = 0;
+       mt_stackshot_task(task, &instrs, &cycles);
+
+       kern_return_t error = KERN_SUCCESS;
+       mach_vm_address_t out_addr = 0;
+       kcd_exit_on_error(kcdata_get_memory_addr(kcd, STACKSHOT_KCTYPE_INSTRS_CYCLES, sizeof(struct instrs_cycles_snapshot), &out_addr));
+       struct instrs_cycles_snapshot *instrs_cycles = (struct instrs_cycles_snapshot *)out_addr;
+       instrs_cycles->ics_instructions = instrs;
+       instrs_cycles->ics_cycles = cycles;
+
+error_exit:
+       return error;
+}
+#endif /* MONOTONIC */
+
 static kern_return_t
 kcdata_record_task_snapshot(kcdata_descriptor_t kcd, task_t task, uint32_t trace_flags, boolean_t have_pmap, unaligned_u64 **task_snap_ss_flags)
 {
@@ -1154,13 +1173,7 @@ kcdata_record_task_snapshot(kcdata_descriptor_t kcd, task_t task, uint32_t trace
 
 #if MONOTONIC
        if (collect_instrs_cycles) {
-               uint64_t instrs = 0, cycles = 0;
-               mt_stackshot_task(task, &instrs, &cycles);
-
-               kcd_exit_on_error(kcdata_get_memory_addr(kcd, STACKSHOT_KCTYPE_INSTRS_CYCLES, sizeof(struct instrs_cycles_snapshot), &out_addr));
-               struct instrs_cycles_snapshot *instrs_cycles = (struct instrs_cycles_snapshot *)out_addr;
-               instrs_cycles->ics_instructions = instrs;
-               instrs_cycles->ics_cycles = cycles;
+               kcd_exit_on_error(kcdata_record_task_instrs_cycles(kcd, task));
        }
 #endif /* MONOTONIC */
 
@@ -1169,11 +1182,16 @@ error_exit:
 }
 
 static kern_return_t
-kcdata_record_task_delta_snapshot(kcdata_descriptor_t kcd, task_t task, boolean_t have_pmap, unaligned_u64 **task_snap_ss_flags)
+kcdata_record_task_delta_snapshot(kcdata_descriptor_t kcd, task_t task, uint32_t trace_flags, boolean_t have_pmap, unaligned_u64 **task_snap_ss_flags)
 {
        kern_return_t error                       = KERN_SUCCESS;
        struct task_delta_snapshot_v2 * cur_tsnap = NULL;
        mach_vm_address_t out_addr                = 0;
+#if MONOTONIC
+       boolean_t collect_instrs_cycles           = ((trace_flags & STACKSHOT_INSTRS_CYCLES) != 0);
+#else
+       (void)trace_flags;
+#endif /* MONOTONIC */
 
        uint64_t task_uniqueid = get_task_uniqueid(task);
        assert(task_snap_ss_flags != NULL);
@@ -1206,6 +1224,12 @@ kcdata_record_task_delta_snapshot(kcdata_descriptor_t kcd, task_t task, boolean_
                                         ? LATENCY_QOS_TIER_UNSPECIFIED
                                         : ((0xFF << 16) | task-> effective_policy.tep_latency_qos);
 
+#if MONOTONIC
+       if (collect_instrs_cycles) {
+               kcd_exit_on_error(kcdata_record_task_instrs_cycles(kcd, task));
+       }
+#endif /* MONOTONIC */
+
 error_exit:
        return error;
 }
@@ -1453,7 +1477,7 @@ error_exit:
 }
 
 static int
-kcdata_record_thread_delta_snapshot(struct thread_delta_snapshot_v2 * cur_thread_snap, thread_t thread, boolean_t thread_on_core)
+kcdata_record_thread_delta_snapshot(struct thread_delta_snapshot_v3 * cur_thread_snap, thread_t thread, boolean_t thread_on_core)
 {
        cur_thread_snap->tds_thread_id = thread_tid(thread);
        if (IPC_VOUCHER_NULL != thread->ith_voucher)
@@ -1485,6 +1509,11 @@ kcdata_record_thread_delta_snapshot(struct thread_delta_snapshot_v2 * cur_thread
        cur_thread_snap->tds_rqos_override           = thread->requested_policy.thrp_qos_override;
        cur_thread_snap->tds_io_tier                 = proc_get_effective_thread_policy(thread, TASK_POLICY_IO);
 
+       static_assert(sizeof(thread->effective_policy) == sizeof(uint64_t));
+       static_assert(sizeof(thread->requested_policy) == sizeof(uint64_t));
+       cur_thread_snap->tds_requested_policy = *(unaligned_u64 *) &thread->requested_policy;
+       cur_thread_snap->tds_effective_policy = *(unaligned_u64 *) &thread->effective_policy;
+
        return 0;
 }
 
@@ -1760,7 +1789,7 @@ kdp_stackshot_kcdata_format(int pid, uint32_t trace_flags, uint32_t * pBytesTrac
                                if (minimize_nonrunnables) {
                                        // delay taking the task snapshot.  If there are no runnable threads we'll skip it.
                                } else {
-                                       kcd_exit_on_error(kcdata_record_task_delta_snapshot(stackshot_kcdata_p, task, have_pmap, &task_snap_ss_flags));
+                                       kcd_exit_on_error(kcdata_record_task_delta_snapshot(stackshot_kcdata_p, task, trace_flags, have_pmap, &task_snap_ss_flags));
                                }
                        }
 
@@ -1815,7 +1844,7 @@ kdp_stackshot_kcdata_format(int pid, uint32_t trace_flags, uint32_t * pBytesTrac
 
                        if (task_delta_stackshot && minimize_nonrunnables) {
                                if (some_thread_ran || num_delta_thread_snapshots > 0) {
-                                       kcd_exit_on_error(kcdata_record_task_delta_snapshot(stackshot_kcdata_p, task, have_pmap, &task_snap_ss_flags));
+                                       kcd_exit_on_error(kcdata_record_task_delta_snapshot(stackshot_kcdata_p, task, trace_flags, have_pmap, &task_snap_ss_flags));
                                } else {
                                        kcd_exit_on_error(kcdata_undo_add_container_begin(stackshot_kcdata_p));
 
@@ -1831,14 +1860,14 @@ kdp_stackshot_kcdata_format(int pid, uint32_t trace_flags, uint32_t * pBytesTrac
                                }
                        }
 
-                       struct thread_delta_snapshot_v2 * delta_snapshots = NULL;
+                       struct thread_delta_snapshot_v3 * delta_snapshots = NULL;
                        int current_delta_snapshot_index                  = 0;
 
                        if (num_delta_thread_snapshots > 0) {
                                kcd_exit_on_error(kcdata_get_memory_addr_for_array(stackshot_kcdata_p, STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT,
-                                                                                  sizeof(struct thread_delta_snapshot_v2),
+                                                                                  sizeof(struct thread_delta_snapshot_v3),
                                                                                   num_delta_thread_snapshots, &out_addr));
-                               delta_snapshots = (struct thread_delta_snapshot_v2 *)out_addr;
+                               delta_snapshots = (struct thread_delta_snapshot_v3 *)out_addr;
                        }
 
                        uint64_t * nonrunnable_tids   = NULL;
index 21fbbbf349e61a8ab17ce6f669dd1b6e1a197959..96455de011ff9d3db890189646656b109851d5ec 100644 (file)
@@ -45,8 +45,6 @@
 #include <kperf/context.h>
 #include <kperf/action.h>
 
-#include <chud/chud_xnu.h>
-
 uint32_t kpc_actionid[KPC_MAX_COUNTERS];
 
 #define COUNTERBUF_SIZE_PER_CPU (KPC_MAX_COUNTERS * sizeof(uint64_t))
@@ -152,9 +150,9 @@ kpc_task_set_forced_all_ctrs(task_t task, boolean_t state)
 
        task_lock(task);
        if (state)
-               task->t_chud |= TASK_KPC_FORCED_ALL_CTRS;
+               task->t_kpc |= TASK_KPC_FORCED_ALL_CTRS;
        else
-               task->t_chud &= ~TASK_KPC_FORCED_ALL_CTRS;
+               task->t_kpc &= ~TASK_KPC_FORCED_ALL_CTRS;
        task_unlock(task);
 }
 
@@ -162,7 +160,7 @@ static boolean_t
 kpc_task_get_forced_all_ctrs(task_t task)
 {
        assert(task);
-       return task->t_chud & TASK_KPC_FORCED_ALL_CTRS ? TRUE : FALSE;
+       return task->t_kpc & TASK_KPC_FORCED_ALL_CTRS ? TRUE : FALSE;
 }
 
 int
index 1f5c7816a973776cc5f570c6af2e48918c04b432..a4d4cbcdb28e7a9e7bb0f23109984e85dda02abe 100644 (file)
@@ -146,6 +146,7 @@ extern void machine_max_runnable_latency(uint64_t bg_max_latency,
 
 extern void machine_work_interval_notify(thread_t thread, struct kern_work_interval_args* kwi_args);
 
+
 extern void machine_perfcontrol_deadline_passed(uint64_t deadline);
 
 extern void machine_switch_perfcontrol_context(perfcontrol_event event,
index d61fb3584b78ef3cce6068177173eca5b6edc9dd..29ee2506fcbabc9cd0d195cf7b41c9405042de33 100644 (file)
@@ -394,7 +394,7 @@ lightweight_update_priority(thread_t thread)
                                              (uintptr_t)thread_tid(thread),
                                              thread->base_pri,
                                              thread->sched_pri,
-                                             0, /* eventually, 'reason' */
+                                             thread->sched_usage,
                                              0);
                }
        }
@@ -582,7 +582,7 @@ update_priority(
                                              (uintptr_t)thread_tid(thread),
                                              thread->base_pri,
                                              thread->sched_pri,
-                                             0, /* eventually, 'reason' */
+                                             thread->sched_usage,
                                              0);
 
                        if (removed)
index 24df80d882454719a75c38626c1fbd0b40daad59..fd945ba1c8d9ef93b191d8f3cad09d95795400ce 100644 (file)
@@ -287,6 +287,9 @@ sched_multiq_processor_queue_shutdown(processor_t processor);
 static sched_mode_t
 sched_multiq_initial_thread_sched_mode(task_t parent_task);
 
+static bool
+sched_multiq_thread_avoid_processor(processor_t processor, thread_t thread);
+
 const struct sched_dispatch_table sched_multiq_dispatch = {
        .sched_name                                     = "multiq",
        .init                                           = sched_multiq_init,
@@ -319,8 +322,8 @@ const struct sched_dispatch_table sched_multiq_dispatch = {
        .direct_dispatch_to_idle_processors             = FALSE,
        .multiple_psets_enabled                         = FALSE,
        .sched_groups_enabled                           = TRUE,
-       .avoid_processor_enabled                        = FALSE,
-       .thread_avoid_processor                         = NULL,
+       .avoid_processor_enabled                        = TRUE,
+       .thread_avoid_processor                         = sched_multiq_thread_avoid_processor,
        .processor_balance                              = sched_SMT_balance,
 
        .rt_runq                                        = sched_rtglobal_runq,
@@ -1197,6 +1200,10 @@ sched_multiq_processor_csw_check(processor_t processor)
        boolean_t       has_higher;
        int             pri;
 
+       if (sched_multiq_thread_avoid_processor(processor, current_thread())) {
+               return (AST_PREEMPT | AST_URGENT);
+       }
+
        entry_queue_t main_entryq = multiq_main_entryq(processor);
        run_queue_t   bound_runq  = multiq_bound_runq(processor);
 
@@ -1468,3 +1475,22 @@ sched_multiq_thread_update_scan(sched_update_scan_context_t scan_context)
 
        } while (restart_needed);
 }
+
+extern int sched_allow_rt_smt;
+
+/* Return true if this thread should not continue running on this processor */
+static bool
+sched_multiq_thread_avoid_processor(processor_t processor, thread_t thread)
+{
+       if (processor->processor_primary != processor) {
+               /*
+                * This is a secondary SMT processor.  If the primary is running
+                * a realtime thread, only allow realtime threads on the secondary.
+                */
+               if ((processor->processor_primary->current_pri >= BASEPRI_RTQUEUES) && ((thread->sched_pri < BASEPRI_RTQUEUES) || !sched_allow_rt_smt)) {
+                       return true;
+               }
+       }
+
+       return false;
+}
index 5f7be7132c5f4f57f654ec6ac17d0a17d628b359..508c83bdb7064911c71ac3e4c820e7c532c9b732 100644 (file)
@@ -1777,6 +1777,10 @@ sched_SMT_balance(__unused processor_t cprocessor, processor_set_t cpset)
 }
 #endif /* __SMP__ */
 
+static processor_t choose_processor_for_realtime_thread(processor_set_t pset);
+static bool all_available_primaries_are_running_realtime_threads(processor_set_t pset);
+int sched_allow_rt_smt = 1;
+
 /*
  *     thread_select:
  *
@@ -1825,9 +1829,19 @@ thread_select(thread_t          thread,
                         * An exception is that bound threads are dispatched to a processor without going through
                         * choose_processor(), so in those cases we should continue trying to dequeue work.
                         */
-                       if (!SCHED(processor_bound_count)(processor) &&
-                               !queue_empty(&pset->idle_queue) && !rt_runq_count(pset)) {
-                               goto idle;
+                       if (!SCHED(processor_bound_count)(processor)) {
+                               if (!queue_empty(&pset->idle_queue)) {
+                                       goto idle;
+                               }
+                               
+                               /* There are no idle primaries */
+
+                               if (processor->processor_primary->current_pri >= BASEPRI_RTQUEUES) {
+                                       bool secondary_can_run_realtime_thread = sched_allow_rt_smt && rt_runq_count(pset) && all_available_primaries_are_running_realtime_threads(pset);
+                                       if (!secondary_can_run_realtime_thread) {
+                                               goto idle;
+                                       }
+                               }
                        }
                }
 
@@ -1888,8 +1902,22 @@ thread_select(thread_t          thread,
                                processor->deadline = thread->realtime.deadline;
 
                                sched_update_pset_load_average(pset);
+
+                               processor_t next_rt_processor = PROCESSOR_NULL;
+                               sched_ipi_type_t next_rt_ipi_type = SCHED_IPI_NONE;
+
+                               if (rt_runq_count(pset) > 0) {
+                                       next_rt_processor = choose_processor_for_realtime_thread(pset);
+                                       if (next_rt_processor) {
+                                               next_rt_ipi_type = sched_ipi_action(next_rt_processor, NULL, false, SCHED_IPI_EVENT_PREEMPT);
+                                       }
+                               }
                                pset_unlock(pset);
 
+                               if (next_rt_processor) {
+                                       sched_ipi_perform(next_rt_processor, next_rt_ipi_type);
+                               }
+
                                return (thread);
                        }
 
@@ -1916,27 +1944,55 @@ thread_select(thread_t          thread,
                if (rt_runq_count(pset) > 0) {
 
                        rt_lock_lock(pset);
-               
+
                        if (rt_runq_count(pset) > 0) {
-                           thread_t next_rt = qe_queue_first(&SCHED(rt_runq)(pset)->queue, struct thread, runq_links);
+                               thread_t next_rt = qe_queue_first(&SCHED(rt_runq)(pset)->queue, struct thread, runq_links);
 
-                           if (__probable((next_rt->bound_processor == PROCESSOR_NULL ||
-                                      (next_rt->bound_processor == processor)))) {
+                               if (__probable((next_rt->bound_processor == PROCESSOR_NULL ||
+                                               (next_rt->bound_processor == processor)))) {
 pick_new_rt_thread:
-                                   new_thread = qe_dequeue_head(&SCHED(rt_runq)(pset)->queue, struct thread, runq_links);
+                                       new_thread = qe_dequeue_head(&SCHED(rt_runq)(pset)->queue, struct thread, runq_links);
 
-                                   new_thread->runq = PROCESSOR_NULL;
-                                   SCHED_STATS_RUNQ_CHANGE(&SCHED(rt_runq)(pset)->runq_stats, rt_runq_count(pset));
-                                   rt_runq_count_decr(pset);
+                                       new_thread->runq = PROCESSOR_NULL;
+                                       SCHED_STATS_RUNQ_CHANGE(&SCHED(rt_runq)(pset)->runq_stats, rt_runq_count(pset));
+                                       rt_runq_count_decr(pset);
 
-                                   processor->deadline = new_thread->realtime.deadline;
+                                       processor->deadline = new_thread->realtime.deadline;
+                                       processor_state_update_from_thread(processor, new_thread);
 
-                                   rt_lock_unlock(pset);
-                                   sched_update_pset_load_average(pset);
-                                   pset_unlock(pset);
+                                       rt_lock_unlock(pset);
+                                       sched_update_pset_load_average(pset);
+
+                                       processor_t ast_processor = PROCESSOR_NULL;
+                                       processor_t next_rt_processor = PROCESSOR_NULL;
+                                       sched_ipi_type_t ipi_type = SCHED_IPI_NONE;
+                                       sched_ipi_type_t next_rt_ipi_type = SCHED_IPI_NONE;
+
+                                       if (processor->processor_secondary != NULL) {
+                                               processor_t sprocessor = processor->processor_secondary;
+                                               if ((sprocessor->state == PROCESSOR_RUNNING) || (sprocessor->state == PROCESSOR_DISPATCHING)) {
+                                                       ipi_type = sched_ipi_action(sprocessor, NULL, false, SCHED_IPI_EVENT_SMT_REBAL);
+                                                       ast_processor = sprocessor;
+                                               }
+                                       }
+                                       if (rt_runq_count(pset) > 0) {
+                                               next_rt_processor = choose_processor_for_realtime_thread(pset);
+                                               if (next_rt_processor) {
+                                                       next_rt_ipi_type = sched_ipi_action(next_rt_processor, NULL, false, SCHED_IPI_EVENT_PREEMPT);
+                                               }
+                                       }
+                                       pset_unlock(pset);
+
+                                       if (ast_processor) {
+                                               sched_ipi_perform(ast_processor, ipi_type);
+                                       }
 
-                                   return (new_thread);
-                           }
+                                       if (next_rt_processor) {
+                                               sched_ipi_perform(next_rt_processor, next_rt_ipi_type);
+                                       }
+
+                                       return (new_thread);
+                               }
                        }
 
                        rt_lock_unlock(pset);
@@ -1947,6 +2003,7 @@ pick_new_rt_thread:
                /* No RT threads, so let's look at the regular threads. */
                if ((new_thread = SCHED(choose_thread)(processor, MINPRI, *reason)) != THREAD_NULL) {
                        sched_update_pset_load_average(pset);
+                       processor_state_update_from_thread(processor, new_thread);
                        pset_unlock(pset);
                        return (new_thread);
                }
@@ -3736,12 +3793,14 @@ choose_processor(
         */
 
        integer_t lowest_priority = MAXPRI + 1;
+       integer_t lowest_secondary_priority = MAXPRI + 1;
        integer_t lowest_unpaired_primary_priority = MAXPRI + 1;
        integer_t lowest_count = INT_MAX;
        uint64_t  furthest_deadline = 1;
        processor_t lp_processor = PROCESSOR_NULL;
        processor_t lp_unpaired_primary_processor = PROCESSOR_NULL;
        processor_t lp_unpaired_secondary_processor = PROCESSOR_NULL;
+       processor_t lp_paired_secondary_processor = PROCESSOR_NULL;
        processor_t lc_processor = PROCESSOR_NULL;
        processor_t fd_processor = PROCESSOR_NULL;
 
@@ -3767,12 +3826,15 @@ choose_processor(
                 * Choose an idle processor, in pset traversal order
                 */
                qe_foreach_element(processor, &cset->idle_queue, processor_queue) {
+                       if (bit_test(cset->pending_AST_cpu_mask, processor->cpu_id)) {
+                               continue;
+                       }
                        if (processor->is_recommended)
                                return processor;
                }
 
                /*
-                * Otherwise, enumerate active and idle processors to find candidates
+                * Otherwise, enumerate active and idle processors to find primary candidates
                 * with lower priority/etc.
                 */
 
@@ -3781,11 +3843,21 @@ choose_processor(
                        if (!processor->is_recommended) {
                                continue;
                        }
+                       if (bit_test(cset->pending_AST_cpu_mask, processor->cpu_id)) {
+                               continue;
+                       }
 
                        integer_t cpri = processor->current_pri;
-                       if (cpri < lowest_priority) {
-                               lowest_priority = cpri;
-                               lp_processor = processor;
+                       if (processor->processor_primary != processor) {
+                               if (cpri < lowest_secondary_priority) {
+                                       lowest_secondary_priority = cpri;
+                                       lp_paired_secondary_processor = processor;
+                               }
+                       } else {
+                               if (cpri < lowest_priority) {
+                                       lowest_priority = cpri;
+                                       lp_processor = processor;
+                               }
                        }
 
                        if ((cpri >= BASEPRI_RTQUEUES) && (processor->deadline > furthest_deadline)) {
@@ -3812,6 +3884,10 @@ choose_processor(
 
                        processor_t cprimary = processor->processor_primary;
 
+                       if (bit_test(cset->pending_AST_cpu_mask, cprimary->cpu_id)) {
+                               continue;
+                       }
+
                        /* If the primary processor is offline or starting up, it's not a candidate for this path */
                        if (cprimary->state == PROCESSOR_RUNNING || cprimary->state == PROCESSOR_DISPATCHING) {
                                integer_t primary_pri = cprimary->current_pri;
@@ -3844,6 +3920,9 @@ choose_processor(
                                re_queue_tail(&cset->active_queue, &lp_processor->processor_queue);
                                return lp_processor;
                        }
+                       if (sched_allow_rt_smt && (thread->sched_pri > lowest_secondary_priority)) {
+                               return lp_paired_secondary_processor;
+                       }
                        if (thread->realtime.deadline < furthest_deadline)
                                return fd_processor;
 
@@ -3903,6 +3982,9 @@ choose_processor(
                if (lp_unpaired_secondary_processor != PROCESSOR_NULL) {
                        processor = lp_unpaired_secondary_processor;
                        lp_unpaired_secondary_processor = PROCESSOR_NULL;
+               } else if (lp_paired_secondary_processor != PROCESSOR_NULL) {
+                       processor = lp_paired_secondary_processor;
+                       lp_paired_secondary_processor = PROCESSOR_NULL;
                } else if (lc_processor != PROCESSOR_NULL) {
                        processor = lc_processor;
                        lc_processor = PROCESSOR_NULL;
@@ -4055,10 +4137,10 @@ thread_setrun(
                realtime_setrun(processor, thread);
        } else {
                processor_setrun(processor, thread, options);
-               /* pset is now unlocked */
-               if (thread->bound_processor == PROCESSOR_NULL) {
-                       SCHED(check_spill)(pset, thread);
-               }
+       }
+       /* pset is now unlocked */
+       if (thread->bound_processor == PROCESSOR_NULL) {
+               SCHED(check_spill)(pset, thread);
        }
 }
 
@@ -4224,7 +4306,7 @@ set_sched_pri(
                              (uintptr_t)thread_tid(thread),
                              thread->base_pri,
                              thread->sched_pri,
-                             0, /* eventually, 'reason' */
+                             thread->sched_usage,
                              0);
 
        if (is_current_thread) {
@@ -4513,7 +4595,7 @@ processor_idle(
                if (bit_test(pset->pending_deferred_AST_cpu_mask, processor->cpu_id))
                        break;
 #endif
-               if (processor->is_recommended) {
+               if (processor->is_recommended && (processor->processor_primary == processor)) {
                        if (rt_runq_count(pset))
                                break;
                } else {
@@ -4575,7 +4657,7 @@ processor_idle(
 
                if ((new_thread != THREAD_NULL) && (SCHED(processor_queue_has_priority)(processor, new_thread->sched_pri, FALSE)                                        ||
                                                                                        (rt_runq_count(pset) > 0))      ) {
-                       /* Something higher priority has popped up on the runqueue - redispatch this thread elsewhere */
+                       /* Something higher priority has popped up on the runqueue - redispatch this thread elsewhere */
                        processor_state_update_idle(processor);
                        processor->deadline = UINT64_MAX;
 
@@ -5605,3 +5687,88 @@ sched_update_pset_load_average(processor_set_t pset)
 #if (DEVELOPMENT || DEBUG)
 #endif
 }
+
+/* pset is locked */
+static processor_t
+choose_processor_for_realtime_thread(processor_set_t pset)
+{
+       uint64_t cpu_map = (pset->cpu_bitmask & pset->recommended_bitmask & ~pset->pending_AST_cpu_mask);
+
+       for (int cpuid = lsb_first(cpu_map); cpuid >= 0; cpuid = lsb_next(cpu_map, cpuid)) {
+               processor_t processor = processor_array[cpuid];
+
+               if (processor->processor_primary != processor) {
+                       continue;
+               }
+
+               if (processor->state == PROCESSOR_IDLE) {
+                       return processor;
+               }
+
+               if ((processor->state != PROCESSOR_RUNNING) && (processor->state != PROCESSOR_DISPATCHING)) {
+                       continue;
+               }
+
+               if (processor->current_pri >= BASEPRI_RTQUEUES) {
+                       continue;
+               }
+
+               return processor;
+
+       }
+
+       if (!sched_allow_rt_smt) {
+               return PROCESSOR_NULL;
+       }
+
+       /* Consider secondary processors */
+       for (int cpuid = lsb_first(cpu_map); cpuid >= 0; cpuid = lsb_next(cpu_map, cpuid)) {
+               processor_t processor = processor_array[cpuid];
+
+               if (processor->processor_primary == processor) {
+                       continue;
+               }
+
+               if (processor->state == PROCESSOR_IDLE) {
+                       return processor;
+               }
+
+               if ((processor->state != PROCESSOR_RUNNING) && (processor->state != PROCESSOR_DISPATCHING)) {
+                       continue;
+               }
+
+               if (processor->current_pri >= BASEPRI_RTQUEUES) {
+                       continue;
+               }
+
+               return processor;
+
+       }
+
+       return PROCESSOR_NULL;
+}
+
+/* pset is locked */
+static bool
+all_available_primaries_are_running_realtime_threads(processor_set_t pset)
+{
+       uint64_t cpu_map = (pset->cpu_bitmask & pset->recommended_bitmask);
+
+       for (int cpuid = lsb_first(cpu_map); cpuid >= 0; cpuid = lsb_next(cpu_map, cpuid)) {
+               processor_t processor = processor_array[cpuid];
+
+               if (processor->processor_primary != processor) {
+                       continue;
+               }
+
+               if ((processor->state != PROCESSOR_RUNNING) && (processor->state != PROCESSOR_DISPATCHING)) {
+                       continue;
+               }
+
+               if (processor->current_pri < BASEPRI_RTQUEUES) {
+                       return false;
+               }
+       }
+
+       return true;
+}
index c0014e86bfc61d37d0dab28a50ad5f4f730ee494..c6361a9cac9ecd087b9506ddfb807743ada2ff00 100644 (file)
@@ -467,7 +467,7 @@ extern kern_return_t clear_wait(
                                                wait_result_t   result);
 
 /* Start thread running */
-extern void            thread_bootstrap_return(void);
+extern void            thread_bootstrap_return(void) __attribute__((noreturn));
 
 /* Return from exception (BSD-visible interface) */
 extern void            thread_exception_return(void) __dead2;
index a1a9c563c15616d38b7be4345af0b5833c2d8f14..7685299bd5ef978ab8a014876752a9654fe045bd 100644 (file)
@@ -203,6 +203,7 @@ unsigned int new_nkdbufs = 0;
 unsigned int wake_nkdbufs = 0;
 unsigned int write_trace_on_panic = 0;
 static char trace_typefilter[64] = { 0 };
+unsigned int trace_wrap = 0;
 boolean_t trace_serial = FALSE;
 boolean_t early_boot_complete = FALSE;
 
@@ -265,6 +266,7 @@ kernel_bootstrap(void)
        PE_parse_boot_argn("trace_wake", &wake_nkdbufs, sizeof (wake_nkdbufs));
        PE_parse_boot_argn("trace_panic", &write_trace_on_panic, sizeof(write_trace_on_panic));
        PE_parse_boot_arg_str("trace_typefilter", trace_typefilter, sizeof(trace_typefilter));
+       PE_parse_boot_argn("trace_wrap", &trace_wrap, sizeof(trace_wrap));
 
        scale_setup();
 
@@ -530,7 +532,7 @@ kernel_bootstrap_thread(void)
        kernel_bootstrap_thread_log("ktrace_init");
        ktrace_init();
 
-       kdebug_init(new_nkdbufs, trace_typefilter);
+       kdebug_init(new_nkdbufs, trace_typefilter, trace_wrap);
 
        kernel_bootstrap_log("prng_init");
        prng_cpu_init(master_cpu);
index e944c79d94956f64150b36fb3fa67025a689a17e..27961d85cb50f9fef9d587fdca3bcfd36408d0e6 100644 (file)
@@ -492,7 +492,7 @@ thread_depress_abstime(
                                      (uintptr_t)thread_tid(self),
                                      self->base_pri,
                                      self->sched_pri,
-                                     0, /* eventually, 'reason' */
+                                     self->sched_usage,
                                      0);
 
                myprocessor->current_pri = self->sched_pri;
@@ -596,7 +596,7 @@ thread_poll_yield(
                                                      (uintptr_t)thread_tid(self),
                                                      self->base_pri,
                                                      self->sched_pri,
-                                                     0, /* eventually, 'reason' */
+                                                     self->sched_usage,
                                                      0);
 
                                myprocessor->current_pri = self->sched_pri;
index cb3a359b552d78ab099a7815e8c1cf66dc81ffc8..873779ca9caa0beb119add33dbd41f1058e66c19 100644 (file)
@@ -288,7 +288,12 @@ extern int kevent_proc_copy_uptrs(void *proc, uint64_t *buf, int bufsize);
 extern void    proc_memstat_terminated(struct proc* p, boolean_t set);
 extern void    memorystatus_on_ledger_footprint_exceeded(int warning, boolean_t memlimit_is_active, boolean_t memlimit_is_fatal);
 extern void    memorystatus_log_exception(const int max_footprint_mb, boolean_t memlimit_is_active, boolean_t memlimit_is_fatal);
-extern boolean_t memorystatus_allowed_vm_map_fork(__unused task_t task);
+extern boolean_t memorystatus_allowed_vm_map_fork(task_t task);
+
+#if DEVELOPMENT || DEBUG
+extern void memorystatus_abort_vm_map_fork(task_t);
+#endif
+
 #endif /* CONFIG_MEMORYSTATUS */
 
 #endif /* MACH_BSD */
@@ -390,6 +395,30 @@ task_set_platform_binary(
        task_unlock(task);
 }
 
+/*
+ * Set or clear per-task TF_CA_CLIENT_WI flag according to specified argument.
+ * Returns "false" if flag is already set, and "true" in other cases.
+ */
+bool
+task_set_ca_client_wi(
+               task_t task,
+               boolean_t set_or_clear)
+{
+       bool ret = true;
+       task_lock(task);
+       if (set_or_clear) {
+               /* Tasks can have only one CA_CLIENT work interval */
+               if (task->t_flags & TF_CA_CLIENT_WI)
+                       ret = false;
+               else
+                       task->t_flags |= TF_CA_CLIENT_WI;
+       } else {
+               task->t_flags &= ~TF_CA_CLIENT_WI;
+       }
+       task_unlock(task);
+       return ret;
+}
+
 void
 task_set_dyld_info(
     task_t task, 
@@ -475,7 +504,7 @@ task_clear_return_wait(task_t task)
        task_unlock(task);
 }
 
-void
+void __attribute__((noreturn))
 task_wait_to_return(void)
 {
        task_t task;
@@ -1105,7 +1134,7 @@ task_create_internal(
 
        new_task->affinity_space = NULL;
 
-       new_task->t_chud = 0;
+       new_task->t_kpc = 0;
 
        new_task->pidsuspended = FALSE;
        new_task->frozen = FALSE;
@@ -1227,7 +1256,8 @@ task_create_internal(
        assert(new_task->task_io_stats != NULL);
        bzero(new_task->task_io_stats, sizeof(struct io_stat_info));
 
-       bzero(&(new_task->cpu_time_qos_stats), sizeof(struct _cpu_time_qos_stats));
+       bzero(&(new_task->cpu_time_eqos_stats), sizeof(new_task->cpu_time_eqos_stats));
+       bzero(&(new_task->cpu_time_rqos_stats), sizeof(new_task->cpu_time_rqos_stats));
 
        bzero(&new_task->extmod_statistics, sizeof(new_task->extmod_statistics));
 
@@ -1318,6 +1348,10 @@ task_create_internal(
        new_task->task_nonvolatile_objects = 0;
        new_task->task_purgeable_disowning = FALSE;
        new_task->task_purgeable_disowned = FALSE;
+       queue_init(&new_task->task_objq);
+       task_objq_lock_init(new_task);
+
+       new_task->task_region_footprint = FALSE;
 
 #if CONFIG_SECLUDED_MEMORY
        new_task->task_can_use_secluded_mem = FALSE;
@@ -1372,7 +1406,8 @@ task_rollup_accounting_info(task_t to_task, task_t from_task)
        to_task->purged_memory_critical = from_task->purged_memory_critical;
        to_task->low_mem_privileged_listener = from_task->low_mem_privileged_listener;
        *to_task->task_io_stats = *from_task->task_io_stats;
-       to_task->cpu_time_qos_stats = from_task->cpu_time_qos_stats;
+       to_task->cpu_time_eqos_stats = from_task->cpu_time_eqos_stats;
+       to_task->cpu_time_rqos_stats = from_task->cpu_time_rqos_stats;
        to_task->task_timer_wakeups_bin_1 = from_task->task_timer_wakeups_bin_1;
        to_task->task_timer_wakeups_bin_2 = from_task->task_timer_wakeups_bin_2;
        to_task->task_gpu_ns = from_task->task_gpu_ns;
@@ -1568,6 +1603,8 @@ task_deallocate(
        }
 #endif
 
+       assert(queue_empty(&task->task_objq));
+
        zfree(task_zone, task);
 }
 
@@ -1997,12 +2034,15 @@ task_duplicate_map_and_threads(
                 *
                 * Skip it.
                 */
+#if DEVELOPMENT || DEBUG
+               memorystatus_abort_vm_map_fork(task);
+#endif
                task_resume_internal(task);
                return KERN_FAILURE;
        }
 
        /* Check with VM if vm_map_fork is allowed for this task */
-       if (task_allowed_vm_map_fork(task)) {
+       if (memorystatus_allowed_vm_map_fork(task)) {
 
                /* Setup new task's vmmap, switch from parent task's map to it COW map */
                oldmap = new_task->map;
@@ -2106,16 +2146,6 @@ task_duplicate_map_and_threads(
        return kr;
 }
 
-/*
- * Place holder function to be filled by VM to return
- * TRUE if vm_map_fork is allowed on the given task.
- */
-boolean_t
-task_allowed_vm_map_fork(task_t task __unused)
-{
-       return memorystatus_allowed_vm_map_fork(task);
-}
-
 #if CONFIG_SECLUDED_MEMORY
 extern void task_set_can_use_secluded_mem_locked(
        task_t          task,
@@ -2330,11 +2360,11 @@ task_terminate_internal(
         */
        thread_interrupt_level(interrupt_save);
 
-#if KPERF
+#if KPC
        /* force the task to release all ctrs */
-       if (task->t_chud & TASK_KPC_FORCED_ALL_CTRS)
+       if (task->t_kpc & TASK_KPC_FORCED_ALL_CTRS)
                kpc_force_all_ctrs(task, 0);
-#endif
+#endif /* KPC */
 
 #if CONFIG_COALITIONS
        /*
@@ -4353,6 +4383,8 @@ task_info(
                if (task->itk_space){
                        dbg_info->ipc_space_size = task->itk_space->is_table_size;
                }
+               
+               dbg_info->suspend_count = task->suspend_count;
 
                error = KERN_SUCCESS;
                *task_info_count = TASK_DEBUG_INFO_INTERNAL_COUNT;
@@ -4565,6 +4597,52 @@ task_cpu_ptime(
 }
 
 
+/* This function updates the cpu time in the arrays for each
+ * effective and requested QoS class
+ */
+void
+task_update_cpu_time_qos_stats(
+       task_t  task,
+       uint64_t *eqos_stats,
+       uint64_t *rqos_stats)
+{
+       if (!eqos_stats && !rqos_stats) {
+               return;
+       }
+
+       task_lock(task);
+       thread_t thread;
+       queue_iterate(&task->threads, thread, thread_t, task_threads) {
+               if (thread->options & TH_OPT_IDLE_THREAD) {
+                       continue;
+               }
+
+               thread_update_qos_cpu_time(thread);
+       }
+
+       if (eqos_stats) {
+               eqos_stats[THREAD_QOS_DEFAULT] += task->cpu_time_eqos_stats.cpu_time_qos_default;
+               eqos_stats[THREAD_QOS_MAINTENANCE] += task->cpu_time_eqos_stats.cpu_time_qos_maintenance;
+               eqos_stats[THREAD_QOS_BACKGROUND] += task->cpu_time_eqos_stats.cpu_time_qos_background;
+               eqos_stats[THREAD_QOS_UTILITY] += task->cpu_time_eqos_stats.cpu_time_qos_utility;
+               eqos_stats[THREAD_QOS_LEGACY] += task->cpu_time_eqos_stats.cpu_time_qos_legacy;
+               eqos_stats[THREAD_QOS_USER_INITIATED] += task->cpu_time_eqos_stats.cpu_time_qos_user_initiated;
+               eqos_stats[THREAD_QOS_USER_INTERACTIVE] += task->cpu_time_eqos_stats.cpu_time_qos_user_interactive;
+       }
+
+       if (rqos_stats) {
+               rqos_stats[THREAD_QOS_DEFAULT] += task->cpu_time_rqos_stats.cpu_time_qos_default;
+               rqos_stats[THREAD_QOS_MAINTENANCE] += task->cpu_time_rqos_stats.cpu_time_qos_maintenance;
+               rqos_stats[THREAD_QOS_BACKGROUND] += task->cpu_time_rqos_stats.cpu_time_qos_background;
+               rqos_stats[THREAD_QOS_UTILITY] += task->cpu_time_rqos_stats.cpu_time_qos_utility;
+               rqos_stats[THREAD_QOS_LEGACY] += task->cpu_time_rqos_stats.cpu_time_qos_legacy;
+               rqos_stats[THREAD_QOS_USER_INITIATED] += task->cpu_time_rqos_stats.cpu_time_qos_user_initiated;
+               rqos_stats[THREAD_QOS_USER_INTERACTIVE] += task->cpu_time_rqos_stats.cpu_time_qos_user_interactive;
+       }
+
+       task_unlock(task);
+}
+
 kern_return_t
 task_purgable_info(
        task_t                  task,
@@ -6109,3 +6187,35 @@ task_copy_fields_for_exec(task_t dst_task, task_t src_task)
 {
        dst_task->vtimers = src_task->vtimers;
 }
+
+#if DEVELOPMENT || DEBUG
+int vm_region_footprint = 0;
+#endif /* DEVELOPMENT || DEBUG */
+
+boolean_t
+task_self_region_footprint(void)
+{
+#if DEVELOPMENT || DEBUG
+       if (vm_region_footprint) {
+               /* system-wide override */
+               return TRUE;
+       }
+#endif /* DEVELOPMENT || DEBUG */
+       return current_task()->task_region_footprint;
+}
+
+void
+task_self_region_footprint_set(
+       boolean_t newval)
+{
+       task_t  curtask;
+
+       curtask = current_task();
+       task_lock(curtask);
+       if (newval) {
+               curtask->task_region_footprint = TRUE;
+       } else {
+               curtask->task_region_footprint = FALSE;
+       }
+       task_unlock(curtask);
+}
index 352c50450402de7d42f869d1ca489d91b4861822..f0cbdff1dcce81ff19f6afe823d7b5d2c7afa936 100644 (file)
@@ -256,6 +256,7 @@ struct task {
 #define TF_LRETURNWAIT          0x00000100                              /* task is waiting for fork/posix_spawn/exec to complete */
 #define TF_LRETURNWAITER        0x00000200                              /* task is waiting for TF_LRETURNWAIT to get cleared */
 #define TF_PLATFORM             0x00000400                              /* task is a platform binary */
+#define TF_CA_CLIENT_WI         0x00000800                              /* task has CA_CLIENT work interval */
 
 #define task_has_64BitAddr(task)       \
         (((task)->t_flags & TF_64B_ADDR) != 0)
@@ -301,12 +302,10 @@ struct task {
        mach_vm_address_t       all_image_info_addr; /* dyld __all_image_info     */
        mach_vm_size_t          all_image_info_size; /* section location and size */
 
-#if KPERF
-#define TASK_PMC_FLAG                  0x1     /* Bit in "t_chud" signifying PMC interest */
-#define TASK_KPC_FORCED_ALL_CTRS       0x2     /* Bit in "t_chud" signifying KPC forced all counters */
-
-       uint32_t t_chud;                /* CHUD flags, used for Shark */
-#endif
+#if KPC
+#define TASK_KPC_FORCED_ALL_CTRS       0x2     /* Bit in "t_kpc" signifying this task forced all counters */
+       uint32_t t_kpc; /* kpc flags */
+#endif /* KPC */
 
        boolean_t pidsuspended; /* pid_suspend called; no threads can execute */
        boolean_t frozen;       /* frozen; private resident pages committed to swap */
@@ -371,7 +370,8 @@ struct task {
        /* 
         * The cpu_time_qos_stats fields are protected by the task lock
         */
-       struct _cpu_time_qos_stats      cpu_time_qos_stats;
+       struct _cpu_time_qos_stats      cpu_time_eqos_stats;
+       struct _cpu_time_qos_stats      cpu_time_rqos_stats;
 
        /* Statistics accumulated for terminated threads from this task */
        uint32_t        task_timer_wakeups_bin_1;
@@ -390,6 +390,10 @@ struct task {
        int             task_nonvolatile_objects;
        boolean_t       task_purgeable_disowning;
        boolean_t       task_purgeable_disowned;
+       queue_head_t    task_objq;
+       decl_lck_mtx_data(,task_objq_lock) /* protects "task_objq" */
+
+       boolean_t       task_region_footprint;
 
        /*
         * A task's coalition set is "adopted" in task_create_internal
@@ -426,6 +430,12 @@ struct task {
 #define task_lock_try(task)            lck_mtx_try_lock(&(task)->lock)
 #define task_unlock(task)              lck_mtx_unlock(&(task)->lock)
 
+#define        task_objq_lock_init(task)       lck_mtx_init(&(task)->task_objq_lock, &vm_object_lck_grp, &vm_object_lck_attr)
+#define task_objq_lock(task)           lck_mtx_lock(&(task)->task_objq_lock)
+#define        task_objq_lock_assert_owned(task)       LCK_MTX_ASSERT(&(task)->task_objq_lock, LCK_MTX_ASSERT_OWNED)
+#define task_objq_lock_try(task)       lck_mtx_try_lock(&(task)->task_objq_lock)
+#define task_objq_unlock(task)         lck_mtx_unlock(&(task)->task_objq_lock)
+
 #define        itk_lock_init(task)     lck_mtx_init(&(task)->itk_lock_data, &ipc_lck_grp, &ipc_lck_attr)
 #define        itk_lock_destroy(task)  lck_mtx_destroy(&(task)->itk_lock_data, &ipc_lck_grp)
 #define        itk_lock(task)          lck_mtx_lock(&(task)->itk_lock_data)
@@ -468,7 +478,6 @@ extern void         init_task_ledgers(void);
 extern lck_attr_t      task_lck_attr;
 extern lck_grp_t       task_lck_grp;
 
-
 #else  /* MACH_KERNEL_PRIVATE */
 
 __BEGIN_DECLS
@@ -592,6 +601,10 @@ extern uint64_t            task_energy(
 
 extern uint64_t                task_cpu_ptime(
                                                        task_t   task);
+extern void            task_update_cpu_time_qos_stats(
+                                                       task_t   task,
+                                                       uint64_t *eqos_stats,
+                                                       uint64_t *rqos_stats);
 
 extern void            task_vtimer_set(
                                        task_t          task,
@@ -617,6 +630,9 @@ extern void         task_set_64bit(
 extern void    task_set_platform_binary(
                                        task_t task,
                                        boolean_t is_platform);
+extern bool    task_set_ca_client_wi(
+                                       task_t task,
+                                       boolean_t ca_client_wi);
 
 extern void            task_backing_store_privileged(
                                        task_t          task);
@@ -752,7 +768,7 @@ extern void task_set_32bit_log_flag(task_t task);
 extern boolean_t task_is_active(task_t task);
 extern boolean_t task_is_halting(task_t task);
 extern void task_clear_return_wait(task_t task);
-extern void task_wait_to_return(void);
+extern void task_wait_to_return(void) __attribute__((noreturn));
 extern event_t task_get_return_wait_event(task_t task);
 
 extern void task_atm_reset(task_t task);
@@ -833,6 +849,10 @@ extern void                task_inspect_deallocate(
 
 extern void            task_suspension_token_deallocate(
                                        task_suspension_token_t token);
+
+extern boolean_t task_self_region_footprint(void);
+extern void task_self_region_footprint_set(boolean_t newval);
+
 __END_DECLS
 
 #endif /* _KERN_TASK_H_ */
index f876182a5f525b60dee2008399c60d5e471ee2db..ca3e83f1847af1fb4c20c42be1c4f6eb39fe3dc4 100644 (file)
@@ -3709,16 +3709,13 @@ send_resource_violation(typeof(send_cpu_usage_violation) sendfunc,
                                   HOST_RESOURCE_NOTIFY_PORT, &dstport);
        if (kr)         goto finish;
 
-       /* TH_OPT_HONOR_QLIMIT causes ipc_kmsg_send() to respect the
-        * queue limit.  It also unsets this flag, but this code also
-        * unsets it for clarity and in case that code changes. */
-       curthread->options |= TH_OPT_HONOR_QLIMIT;
+       thread_set_honor_qlimit(curthread);
        kr = sendfunc(dstport,
                      procname, pid, proc_path, timestamp,
                      linfo->lei_balance, linfo->lei_last_refill,
                      linfo->lei_limit, linfo->lei_refill_period,
                      flags);
-       curthread->options &= (~TH_OPT_HONOR_QLIMIT);
+       thread_clear_honor_qlimit(curthread);
 
        ipc_port_release_send(dstport);
 
index ce815db9ef9a20e24c16f330250c1e437584a77c..433a1ae907fa678c45050b6927cc58cf92f3267b 100644 (file)
@@ -542,18 +542,22 @@ thread_terminate_self(void)
 
        bank_swap_thread_bank_ledger(thread, NULL);
 
+       if (kdebug_enable && bsd_hasthreadname(thread->uthread)) {
+               char threadname[MAXTHREADNAMESIZE];
+               bsd_getthreadname(thread->uthread, threadname);
+               kernel_debug_string_simple(TRACE_STRING_THREADNAME_PREV, threadname);
+       }
+
        task = thread->task;
        uthread_cleanup(task, thread->uthread, task->bsd_info);
 
-       if (task->bsd_info && !task_is_exec_copy(task)) {
+       if (kdebug_enable && task->bsd_info && !task_is_exec_copy(task)) {
                /* trace out pid before we sign off */
                long dbg_arg1 = 0;
-               long dbg_arg2 = 0; 
-               
-               kdbg_trace_data(thread->task->bsd_info, &dbg_arg1, &dbg_arg2);
+               long dbg_arg2 = 0;
 
-               KERNEL_DEBUG_CONSTANT(TRACE_DATA_THREAD_TERMINATE_PID | DBG_FUNC_NONE,
-                       dbg_arg1, 0, 0, 0, 0);
+               kdbg_trace_data(thread->task->bsd_info, &dbg_arg1, &dbg_arg2);
+               KDBG_RELEASE(TRACE_DATA_THREAD_TERMINATE_PID, dbg_arg1, dbg_arg2);
        }
 
        /*
@@ -571,14 +575,11 @@ thread_terminate_self(void)
         */
        if (threadcnt == 0 && task->bsd_info != NULL && !task_is_exec_copy(task)) {
                mach_exception_data_type_t subcode = 0;
-               {
+               if (kdebug_enable) {
                        /* since we're the last thread in this process, trace out the command name too */
-                       long    dbg_arg1 = 0, dbg_arg2 = 0, dbg_arg3 = 0, dbg_arg4 = 0;
-
-                       kdbg_trace_string(thread->task->bsd_info, &dbg_arg1, &dbg_arg2, &dbg_arg3, &dbg_arg4);
-
-                       KERNEL_DEBUG_CONSTANT(TRACE_STRING_PROC_EXIT | DBG_FUNC_NONE,
-                               dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4, 0);
+                       long args[4] = {};
+                       kdbg_trace_string(thread->task->bsd_info, &args[0], &args[1], &args[2], &args[3]);
+                       KDBG_RELEASE(TRACE_STRING_PROC_EXIT, args[0], args[1], args[2], args[3]);
                }
 
                /* Get the exit reason before proc_exit */
@@ -703,14 +704,14 @@ thread_deallocate(
 
        task = thread->task;
 
-#ifdef MACH_BSD 
+#ifdef MACH_BSD
        {
                void *ut = thread->uthread;
 
                thread->uthread = NULL;
                uthread_zone_free(ut);
        }
-#endif  /* MACH_BSD */   
+#endif /* MACH_BSD */
 
        if (thread->t_ledger)
                ledger_dereference(thread->t_ledger);
@@ -979,7 +980,7 @@ void
 thread_terminate_enqueue(
        thread_t                thread)
 {
-       KERNEL_DEBUG_CONSTANT(TRACE_DATA_THREAD_TERMINATE | DBG_FUNC_NONE, thread->thread_id, 0, 0, 0, 0);
+       KDBG_RELEASE(TRACE_DATA_THREAD_TERMINATE, thread->thread_id);
 
        simple_lock(&thread_terminate_lock);
        enqueue_tail(&thread_terminate_queue, &thread->runq_links);
@@ -1341,10 +1342,10 @@ thread_create_internal(
        new_thread->corpse_dup = FALSE;
        *out_thread = new_thread;
 
-       {
-               long    dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4;
+       if (kdebug_enable) {
+               long args[4] = {};
 
-               kdbg_trace_data(parent_task->bsd_info, &dbg_arg2, &dbg_arg4);
+               kdbg_trace_data(parent_task->bsd_info, &args[1], &args[3]);
 
                /*
                 * Starting with 26604425, exec'ing creates a new task/thread.
@@ -1352,26 +1353,23 @@ thread_create_internal(
                 * NEWTHREAD in the current process has two possible meanings:
                 *
                 * 1) Create a new thread for this process.
-                * 2) Create a new thread for the future process this will become in an exec.
+                * 2) Create a new thread for the future process this will become in an
+                * exec.
                 *
                 * To disambiguate these, arg3 will be set to TRUE for case #2.
                 *
                 * The value we need to find (TPF_EXEC_COPY) is stable in the case of a
                 * task exec'ing. The read of t_procflags does not take the proc_lock.
                 */
-               dbg_arg3 = (task_is_exec_copy(parent_task)) ? TRUE : 0;
+               args[2] = task_is_exec_copy(parent_task) ? 1 : 0;
 
+               KDBG_RELEASE(TRACE_DATA_NEWTHREAD, (uintptr_t)thread_tid(new_thread),
+                               args[1], args[2], args[3]);
 
-               KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, 
-                       TRACE_DATA_NEWTHREAD | DBG_FUNC_NONE,
-                       (vm_address_t)(uintptr_t)thread_tid(new_thread), dbg_arg2, dbg_arg3, dbg_arg4, 0);
-
-               kdbg_trace_string(parent_task->bsd_info,
-                                                       &dbg_arg1, &dbg_arg2, &dbg_arg3, &dbg_arg4);
-
-               KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, 
-                       TRACE_STRING_NEWTHREAD | DBG_FUNC_NONE,
-                       dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4, 0);
+               kdbg_trace_string(parent_task->bsd_info, &args[0], &args[1],
+                               &args[2], &args[3]);
+               KDBG_RELEASE(TRACE_STRING_NEWTHREAD, args[0], args[1], args[2],
+                               args[3]);
        }
 
        DTRACE_PROC1(lwp__create, thread_t, *out_thread);
@@ -3038,6 +3036,18 @@ thread_set_thread_name(thread_t th, const char* name)
        }
 }
 
+void
+thread_set_honor_qlimit(thread_t thread)
+{
+       thread->options |= TH_OPT_HONOR_QLIMIT;
+}
+
+void
+thread_clear_honor_qlimit(thread_t thread)
+{
+       thread->options &= (~TH_OPT_HONOR_QLIMIT);
+}
+
 /*
  * thread_enable_send_importance - set/clear the SEND_IMPORTANCE thread option bit.
  */
index 4601a9ebb6638c9f2ce6f0cc52b105bfd6f474ec..ca2217584b3ad5fa91efa71b055004e77bc2238a 100644 (file)
@@ -1190,6 +1190,8 @@ extern kern_return_t      kernel_thread_start(
 #ifdef KERNEL_PRIVATE
 void thread_set_eager_preempt(thread_t thread);
 void thread_clear_eager_preempt(thread_t thread);
+void thread_set_honor_qlimit(thread_t thread);
+void thread_clear_honor_qlimit(thread_t thread);
 extern ipc_port_t convert_thread_to_port(thread_t);
 extern ipc_port_t convert_thread_inspect_to_port(thread_inspect_t);
 extern boolean_t is_vm_privileged(void);
index 3bd8b51829f748ea422e7c7040e9e476e984ade1..9c7aa300c8657aab2e3c3bc6f8f458f7cb58720d 100644 (file)
@@ -893,7 +893,7 @@ thread_suspended(__unused void *parameter, wait_result_t result)
                                              (uintptr_t)thread_tid(thread),
                                              thread->base_pri,
                                              thread->sched_pri,
-                                             0, /* eventually, 'reason' */
+                                             thread->sched_usage,
                                              0);
                }
                thread_unlock(thread);
index add093661e856b886002401a03998102595f4eee..6ede110d1ee60ab547ad9bdc531db049fc283654 100644 (file)
@@ -777,20 +777,35 @@ thread_update_qos_cpu_time_locked(thread_t thread)
 
        uint64_t* task_counter = NULL;
 
-       /* Update the task-level qos stats atomically, because we don't have the task lock. */
+       /* Update the task-level effective and requested qos stats atomically, because we don't have the task lock. */
        switch (thread->effective_policy.thep_qos) {
-               case THREAD_QOS_DEFAULT:            task_counter = &task->cpu_time_qos_stats.cpu_time_qos_default;          break;
-               case THREAD_QOS_MAINTENANCE:        task_counter = &task->cpu_time_qos_stats.cpu_time_qos_maintenance;      break;
-               case THREAD_QOS_BACKGROUND:         task_counter = &task->cpu_time_qos_stats.cpu_time_qos_background;       break;
-               case THREAD_QOS_UTILITY:            task_counter = &task->cpu_time_qos_stats.cpu_time_qos_utility;          break;
-               case THREAD_QOS_LEGACY:             task_counter = &task->cpu_time_qos_stats.cpu_time_qos_legacy;           break;
-               case THREAD_QOS_USER_INITIATED:     task_counter = &task->cpu_time_qos_stats.cpu_time_qos_user_initiated;   break;
-               case THREAD_QOS_USER_INTERACTIVE:   task_counter = &task->cpu_time_qos_stats.cpu_time_qos_user_interactive; break;
+               case THREAD_QOS_DEFAULT:            task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_default;          break;
+               case THREAD_QOS_MAINTENANCE:        task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_maintenance;      break;
+               case THREAD_QOS_BACKGROUND:         task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_background;       break;
+               case THREAD_QOS_UTILITY:            task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_utility;          break;
+               case THREAD_QOS_LEGACY:             task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_legacy;           break;
+               case THREAD_QOS_USER_INITIATED:     task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_user_initiated;   break;
+               case THREAD_QOS_USER_INTERACTIVE:   task_counter = &task->cpu_time_eqos_stats.cpu_time_qos_user_interactive; break;
                default:
                        panic("unknown effective QoS: %d", thread->effective_policy.thep_qos);
        }
 
        OSAddAtomic64(timer_delta, task_counter);
+
+       /* Update the task-level qos stats atomically, because we don't have the task lock. */
+       switch (thread->requested_policy.thrp_qos) {
+               case THREAD_QOS_DEFAULT:            task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_default;          break;
+               case THREAD_QOS_MAINTENANCE:        task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_maintenance;      break;
+               case THREAD_QOS_BACKGROUND:         task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_background;       break;
+               case THREAD_QOS_UTILITY:            task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_utility;          break;
+               case THREAD_QOS_LEGACY:             task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_legacy;           break;
+               case THREAD_QOS_USER_INITIATED:     task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_user_initiated;   break;
+               case THREAD_QOS_USER_INTERACTIVE:   task_counter = &task->cpu_time_rqos_stats.cpu_time_qos_user_interactive; break;
+               default:
+                       panic("unknown requested QoS: %d", thread->requested_policy.thrp_qos);
+       }
+
+       OSAddAtomic64(timer_delta, task_counter);
 }
 
 /*
index 93c347ddd0294faa9b0d4093ca5c82adf1433278..86bd1a8df94962b31a5b5209c38bd59ce1487833 100644 (file)
@@ -108,12 +108,13 @@ lck_grp_attr_t          timer_longterm_lck_grp_attr;
 #endif
 
 /*
- * The scan limit throttles processing of the longterm queue.
+ * The scan_limit throttles processing of the longterm queue.
  * If the scan time exceeds this limit, we terminate, unlock 
- * and repeat after this same interval. This prevents unbounded holding of
+ * and defer for scan_interval. This prevents unbounded holding of
  * timer queue locks with interrupts masked.
  */
-#define TIMER_LONGTERM_SCAN_LIMIT      (1ULL * NSEC_PER_MSEC)  /* 1 msec */
+#define TIMER_LONGTERM_SCAN_LIMIT      (100ULL * NSEC_PER_USEC)        /* 100 us */
+#define TIMER_LONGTERM_SCAN_INTERVAL   (100ULL * NSEC_PER_USEC)        /* 100 us */
 /* Sentinel for "scan limit exceeded": */
 #define TIMER_LONGTERM_SCAN_AGAIN      0
 
@@ -141,11 +142,13 @@ typedef struct {
        uint64_t        scan_time;      /* last time the list was scanned */
        threshold_t     threshold;      /* longterm timer threshold */
        uint64_t        scan_limit;     /* maximum scan time */
+       uint64_t        scan_interval;  /* interval between LT "escalation" scans */
        uint64_t        scan_pauses;    /* num scans exceeding time limit */
 } timer_longterm_t;
 
 timer_longterm_t               timer_longterm = {
                                        .scan_limit = TIMER_LONGTERM_SCAN_LIMIT,
+                                       .scan_interval = TIMER_LONGTERM_SCAN_INTERVAL,
                                };
 
 static mpqueue_head_t          *timer_longterm_queue = NULL;
@@ -1492,7 +1495,7 @@ timer_longterm_update_locked(timer_longterm_t *tlp)
        }
        
        /* Throttle next scan time */
-       uint64_t scan_clamp = mach_absolute_time() + tlp->scan_limit;
+       uint64_t scan_clamp = mach_absolute_time() + tlp->scan_interval;
        if (tlp->threshold.deadline_set < scan_clamp)
                tlp->threshold.deadline_set = scan_clamp;
 
@@ -1577,7 +1580,7 @@ timer_longterm_init(void)
 enum {
        THRESHOLD, QCOUNT,
        ENQUEUES, DEQUEUES, ESCALATES, SCANS, PREEMPTS,
-       LATENCY, LATENCY_MIN, LATENCY_MAX, SCAN_LIMIT, PAUSES
+       LATENCY, LATENCY_MIN, LATENCY_MAX, SCAN_LIMIT, SCAN_INTERVAL, PAUSES
 };
 uint64_t
 timer_sysctl_get(int oid)
@@ -1608,6 +1611,8 @@ timer_sysctl_get(int oid)
                return tlp->threshold.latency_max;
        case SCAN_LIMIT:
                return tlp->scan_limit;
+       case SCAN_INTERVAL:
+               return tlp->scan_interval;
        case PAUSES:
                return tlp->scan_pauses;
        default:
@@ -1745,6 +1750,9 @@ timer_sysctl_set(int oid, uint64_t value)
        case SCAN_LIMIT:
                timer_longterm.scan_limit = value;
                return KERN_SUCCESS;
+       case SCAN_INTERVAL:
+               timer_longterm.scan_interval = value;
+               return KERN_SUCCESS;
        default:
                return KERN_INVALID_ARGUMENT;
        }
index 2f4cd62a16cfa7740936e6b03c81c0e7c1464fb5..9e9e189e75bcc346e0bc8cbb9a179c2d3e7b65e7 100644 (file)
@@ -37,6 +37,8 @@
 #include <kern/thread_group.h>
 #include <kern/ipc_kobject.h>
 #include <kern/task.h>
+#include <kern/coalition.h>
+#include <kern/policy_internal.h>
 
 #include <mach/kern_return.h>
 #include <mach/notify.h>
@@ -371,6 +373,20 @@ kern_work_interval_create(thread_t thread,
        uint32_t create_flags = create_params->wica_create_flags;
 
        task_t creating_task = current_task();
+       if ((create_flags & WORK_INTERVAL_TYPE_MASK) == WORK_INTERVAL_TYPE_CA_CLIENT) {
+               /*
+                * CA_CLIENT work intervals do not create new thread groups
+                * and are non-joinable.
+                * There can only be one CA_CLIENT work interval (created by UIKit)
+                * per each application task
+                */
+               if (create_flags & (WORK_INTERVAL_FLAG_JOINABLE | WORK_INTERVAL_FLAG_GROUP))
+                       return (KERN_FAILURE);
+               if (!task_is_app(creating_task))
+                       return (KERN_NOT_SUPPORTED);
+               if (task_set_ca_client_wi(creating_task, true) == false)
+                       return (KERN_FAILURE);
+       }
 
        *work_interval = (struct work_interval) {
                .wi_id                  = work_interval_id,
@@ -406,13 +422,12 @@ kern_work_interval_create(thread_t thread,
        }
 
        create_params->wica_id = work_interval_id;
-
        return KERN_SUCCESS;
 }
 
+
 kern_return_t
-kern_work_interval_destroy(thread_t thread,
-                           uint64_t work_interval_id)
+kern_work_interval_destroy(thread_t thread, uint64_t work_interval_id)
 {
        if (work_interval_id == 0)
                return KERN_INVALID_ARGUMENT;
@@ -454,6 +469,3 @@ kern_work_interval_join(thread_t            thread,
 
        return KERN_SUCCESS;
 }
-
-
-
index 31f009bfaf955678de2bacc3fc4909e446b54bbc..baa2311bac46b4ef8d551fc41a1e3f6eb13afb32 100644 (file)
@@ -63,12 +63,12 @@ struct kern_work_interval_create_args {
  */
 extern kern_return_t
 kern_work_interval_create(thread_t thread, struct kern_work_interval_create_args *create_params);
+
 extern kern_return_t
 kern_work_interval_destroy(thread_t thread, uint64_t work_interval_id);
 extern kern_return_t
 kern_work_interval_join(thread_t thread, mach_port_name_t port_name);
 
-
 extern kern_return_t
 kern_work_interval_notify(thread_t thread, struct kern_work_interval_args* kwi_args);
 
index 0a21dda6a1e6b7fc06ea8e420b9e4a9e3cdc5721..8da4fe3c8df6d282ec76e36f3bf1d58c636bc578 100644 (file)
@@ -72,6 +72,7 @@
 #include <mach/machine/vm_types.h>
 #include <mach_debug/zone_info.h>
 #include <mach/vm_map.h>
+#include <mach/sdt.h>
 
 #include <kern/bits.h>
 #include <kern/kern_types.h>
@@ -445,6 +446,7 @@ struct zone_page_metadata {
 /* Magic value to indicate empty element free list */
 #define PAGE_METADATA_EMPTY_FREELIST           ((uint32_t)(~0))
 
+boolean_t get_zone_info(zone_t z, mach_zone_name_t *zn, mach_zone_info_t *zi);
 boolean_t is_zone_map_nearing_exhaustion(void);
 extern void vm_pageout_garbage_collect(int collect);
 
@@ -3339,6 +3341,8 @@ zalloc_internal(
        }
 #endif
 
+       DTRACE_VM2(zalloc, zone_t, zone, void*, addr);
+
        return((void *)addr);
 }
 
@@ -3478,6 +3482,7 @@ zfree(
 #endif /* VM_MAX_TAG_ZONES */
 
        assert(zone != ZONE_NULL);
+       DTRACE_VM2(zfree, zone_t, zone, void*, addr);
 
 #if KASAN_ZALLOC
        /*
@@ -3868,6 +3873,48 @@ consider_zone_gc(boolean_t consider_jetsams)
                zone_gc(consider_jetsams);
 }
 
+
+boolean_t
+get_zone_info(
+       zone_t                          z,
+       mach_zone_name_t        *zn,
+       mach_zone_info_t        *zi)
+{
+       struct zone zcopy;
+
+       assert(z != ZONE_NULL);
+       lock_zone(z);
+       if (!z->zone_valid) {
+               unlock_zone(z);
+               return FALSE;
+       }
+       zcopy = *z;
+       unlock_zone(z);
+
+       if (zn != NULL) {
+               /* assuming here the name data is static */
+               (void) __nosan_strlcpy(zn->mzn_name, zcopy.zone_name,
+                               strlen(zcopy.zone_name)+1);
+       }
+
+       if (zi != NULL) {
+               zi->mzi_count = (uint64_t)zcopy.count;
+               zi->mzi_cur_size = ptoa_64(zcopy.page_count);
+               zi->mzi_max_size = (uint64_t)zcopy.max_size;
+               zi->mzi_elem_size = (uint64_t)zcopy.elem_size;
+               zi->mzi_alloc_size = (uint64_t)zcopy.alloc_size;
+               zi->mzi_sum_size = zcopy.sum_count * zcopy.elem_size;
+               zi->mzi_exhaustible = (uint64_t)zcopy.exhaustible;
+               zi->mzi_collectable = 0;
+               if (zcopy.collectable) {
+                       SET_MZI_COLLECTABLE_BYTES(zi->mzi_collectable, ((uint64_t)zcopy.count_all_free_pages * PAGE_SIZE));
+                       SET_MZI_COLLECTABLE_FLAG(zi->mzi_collectable, TRUE);
+               }
+       }
+
+       return TRUE;
+}
+
 kern_return_t
 task_zone_info(
        __unused task_t                                 task,
@@ -3916,7 +3963,6 @@ mach_memory_info(
         unsigned int           num_info;
 
        unsigned int            max_zones, used_zones, i;
-       zone_t                  z;
        mach_zone_name_t        *zn;
        mach_zone_info_t        *zi;
        kern_return_t           kr;
@@ -3963,40 +4009,26 @@ mach_memory_info(
 
        used_zones = max_zones;
        for (i = 0; i < max_zones; i++) {
-               struct zone zcopy;
-               z = &(zone_array[i]);
-               assert(z != ZONE_NULL);
-
-               lock_zone(z);
-               if (!z->zone_valid) {
-                       unlock_zone(z);
+               if (!get_zone_info(&(zone_array[i]), zn, zi)) {
                        used_zones--;
                        continue;
                }
-               zcopy = *z;
-               unlock_zone(z);
-
-               /* assuming here the name data is static */
-               (void) __nosan_strncpy(zn->mzn_name, zcopy.zone_name,
-                              sizeof zn->mzn_name);
-               zn->mzn_name[sizeof zn->mzn_name - 1] = '\0';
-
-               zi->mzi_count = (uint64_t)zcopy.count;
-               zi->mzi_cur_size = ptoa_64(zcopy.page_count);
-               zi->mzi_max_size = (uint64_t)zcopy.max_size;
-               zi->mzi_elem_size = (uint64_t)zcopy.elem_size;
-               zi->mzi_alloc_size = (uint64_t)zcopy.alloc_size;
-               zi->mzi_sum_size = zcopy.sum_count * zcopy.elem_size;
-               zi->mzi_exhaustible = (uint64_t)zcopy.exhaustible;
-               zi->mzi_collectable = (uint64_t)zcopy.collectable;
-               zones_collectable_bytes += ((uint64_t)zcopy.count_all_free_pages * PAGE_SIZE);
+               zones_collectable_bytes += GET_MZI_COLLECTABLE_BYTES(zi->mzi_collectable);
                zn++;
                zi++;
        }
 
        used = used_zones * sizeof *names;
-       if (used != names_size)
-               bzero((char *) (names_addr + used), names_size - used);
+       if (used != names_size) {
+               vm_offset_t names_addr_end = names_addr + used;
+               vm_size_t free_size = names_size - (round_page(names_addr_end) - names_addr);
+
+               if (free_size >= PAGE_SIZE) {
+                       kmem_free(ipc_kernel_map,
+                                       round_page(names_addr_end), free_size);
+               }
+               bzero((char *) names_addr_end, round_page(names_addr_end) - names_addr_end);
+       }
 
        kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)names_addr,
                           (vm_map_size_t)used, TRUE, &copy);
@@ -4006,9 +4038,16 @@ mach_memory_info(
        *namesCntp = used_zones;
 
        used = used_zones * sizeof *info;
+       if (used != info_size) {
+               vm_offset_t info_addr_end = info_addr + used;
+               vm_size_t free_size = info_size - (round_page(info_addr_end) - info_addr);
 
-       if (used != info_size)
-               bzero((char *) (info_addr + used), info_size - used);
+               if (free_size >= PAGE_SIZE) {
+                       kmem_free(ipc_kernel_map,
+                                       round_page(info_addr_end), free_size);
+               }
+               bzero((char *) info_addr_end, round_page(info_addr_end) - info_addr_end);
+       }
 
        kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)info_addr,
                           (vm_map_size_t)used, TRUE, &copy);
@@ -4028,10 +4067,6 @@ mach_memory_info(
                kr = kmem_alloc_pageable(ipc_kernel_map,
                                         &memory_info_addr, memory_info_vmsize, VM_KERN_MEMORY_IPC);
                if (kr != KERN_SUCCESS) {
-                       kmem_free(ipc_kernel_map,
-                                 names_addr, names_size);
-                       kmem_free(ipc_kernel_map,
-                                 info_addr, info_size);
                        return kr;
                }
 
@@ -4056,24 +4091,91 @@ mach_memory_info(
        return KERN_SUCCESS;
 }
 
+kern_return_t
+mach_zone_info_for_zone(
+       host_priv_t                     host,
+       mach_zone_name_t        name,
+       mach_zone_info_t        *infop)
+{
+       unsigned int max_zones, i;
+       zone_t zone_ptr;
+
+       if (host == HOST_NULL)
+               return KERN_INVALID_HOST;
+#if CONFIG_DEBUGGER_FOR_ZONE_INFO
+       if (!PE_i_can_has_debugger(NULL))
+               return KERN_INVALID_HOST;
+#endif
+
+       if (infop == NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
+
+       simple_lock(&all_zones_lock);
+       max_zones = (unsigned int)(num_zones);
+       simple_unlock(&all_zones_lock);
+
+       zone_ptr = ZONE_NULL;
+       for (i = 0; i < max_zones; i++) {
+               zone_t z = &(zone_array[i]);
+               assert(z != ZONE_NULL);
+
+               /* Find the requested zone by name */
+               if (!strncmp(name.mzn_name, z->zone_name, strlen(z->zone_name))) {
+                       zone_ptr = z;
+                       break;
+               }
+       }
+
+       /* No zones found with the requested zone name */
+       if (zone_ptr == ZONE_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
+
+       if (get_zone_info(zone_ptr, NULL, infop)) {
+               return KERN_SUCCESS;
+       }
+       return KERN_FAILURE;
+}
+
+kern_return_t
+mach_zone_info_for_largest_zone(
+       host_priv_t                     host,
+       mach_zone_name_t        *namep,
+       mach_zone_info_t        *infop)
+{
+       if (host == HOST_NULL)
+               return KERN_INVALID_HOST;
+#if CONFIG_DEBUGGER_FOR_ZONE_INFO
+       if (!PE_i_can_has_debugger(NULL))
+               return KERN_INVALID_HOST;
+#endif
+
+       if (namep == NULL || infop == NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
+
+       if (get_zone_info(zone_find_largest(), namep, infop)) {
+               return KERN_SUCCESS;
+       }
+       return KERN_FAILURE;
+}
+
 uint64_t
 get_zones_collectable_bytes(void)
 {
-       zone_t z;
        unsigned int i, max_zones;
        uint64_t zones_collectable_bytes = 0;
+       mach_zone_info_t zi;
 
        simple_lock(&all_zones_lock);
        max_zones = (unsigned int)(num_zones);
        simple_unlock(&all_zones_lock);
 
        for (i = 0; i < max_zones; i++) {
-               z = &(zone_array[i]);
-               assert(z != ZONE_NULL);
-
-               lock_zone(z);
-               zones_collectable_bytes += ((uint64_t)z->count_all_free_pages * PAGE_SIZE);
-               unlock_zone(z);
+               if (get_zone_info(&(zone_array[i]), NULL, &zi)) {
+                       zones_collectable_bytes += GET_MZI_COLLECTABLE_BYTES(zi.mzi_collectable);
+               }
        }
 
        return zones_collectable_bytes;
index 7c8f0a7e79c71d226a752e2cba6fcd210410c288..2fe676882634e2daa2a957ad8ffd64f3364179fe 100644 (file)
@@ -28,7 +28,6 @@
 
 /* Collect kernel callstacks */
 
-#include <chud/chud_xnu.h>
 #include <mach/mach_types.h>
 #include <kern/thread.h>
 #include <kern/backtrace.h>
@@ -257,6 +256,10 @@ kperf_backtrace_sample(struct callstack *cs, struct kperf_context *context)
        BUF_VERB(PERF_CS_BACKTRACE | DBG_FUNC_END, cs->nframes);
 }
 
+kern_return_t chudxnu_thread_get_callstack64_kperf(thread_t thread,
+               uint64_t *callStack, mach_msg_type_number_t *count,
+               boolean_t user_only);
+
 void
 kperf_kcallstack_sample(struct callstack *cs, struct kperf_context *context)
 {
@@ -437,3 +440,1058 @@ kperf_ucallstack_pend(struct kperf_context * context, uint32_t depth)
 
        return did_pend;
 }
+
+static kern_return_t
+chudxnu_kern_read(void *dstaddr, vm_offset_t srcaddr, vm_size_t size)
+{
+       return ((ml_nofault_copy(srcaddr, (vm_offset_t)dstaddr, size) == size) ?
+                       KERN_SUCCESS : KERN_FAILURE);
+}
+
+static kern_return_t
+chudxnu_task_read(
+               task_t      task,
+               void        *kernaddr,
+               uint64_t    usraddr,
+               vm_size_t   size)
+{
+       //ppc version ported to arm
+       kern_return_t ret = KERN_SUCCESS;
+
+       if (ml_at_interrupt_context()) {
+               return KERN_FAILURE;    // can't look at tasks on interrupt stack
+       }
+
+       if (current_task() == task) {
+               thread_t      cur_thr = current_thread();
+               vm_offset_t   recover_handler = cur_thr->recover; 
+
+               if (copyin(usraddr, kernaddr, size)) {
+                       ret = KERN_FAILURE;
+               }
+               cur_thr->recover = recover_handler;
+       } else {
+               vm_map_t map = get_task_map(task);
+               ret = vm_map_read_user(map, usraddr, kernaddr, size);
+       }
+
+       return ret;
+}
+
+static inline uint64_t
+chudxnu_vm_unslide( uint64_t ptr, int kaddr )
+{
+       if (!kaddr)
+               return ptr;
+
+       return VM_KERNEL_UNSLIDE(ptr);
+}
+
+#if __arm__
+#define ARM_SUPERVISOR_MODE(cpsr) ((((cpsr) & PSR_MODE_MASK) != PSR_USER_MODE) ? TRUE : FALSE)
+#define CS_FLAG_EXTRASP  1  // capture extra sp register
+static kern_return_t
+chudxnu_thread_get_callstack64_internal(
+       thread_t                thread,
+       uint64_t                *callStack,
+       mach_msg_type_number_t  *count,
+       boolean_t               user_only,
+       int flags)
+{
+       kern_return_t kr;
+       task_t                  task;
+       uint64_t                currPC=0ULL, currLR=0ULL, currSP=0ULL;
+       uint64_t                prevPC = 0ULL;
+       uint32_t                kernStackMin = thread->kernel_stack;
+       uint32_t                kernStackMax = kernStackMin + kernel_stack_size;
+       uint64_t       *buffer = callStack;
+       uint32_t                frame[2];
+       int             bufferIndex = 0;
+       int             bufferMaxIndex = 0;
+       boolean_t       supervisor = FALSE;
+       struct arm_saved_state *state = NULL;
+       uint32_t                *fp=NULL, *nextFramePointer=NULL, *topfp=NULL;
+       uint64_t                pc = 0ULL;
+
+       task = get_threadtask(thread);
+
+       bufferMaxIndex = *count;
+       //get thread state
+       if (user_only)
+               state = find_user_regs(thread);
+       else
+               state = find_kern_regs(thread);
+
+       if (!state) {
+               *count = 0; 
+               return KERN_FAILURE;
+       }
+
+       /* make sure it is safe to dereference before you do it */
+       supervisor = ARM_SUPERVISOR_MODE(state->cpsr);
+
+       /* can't take a kernel callstack if we've got a user frame */
+       if( !user_only && !supervisor )
+               return KERN_FAILURE;
+
+       /*
+       * Reserve space for saving LR (and sometimes SP) at the end of the
+       * backtrace.
+       */
+       if (flags & CS_FLAG_EXTRASP) {
+               bufferMaxIndex -= 2;
+       } else {
+               bufferMaxIndex -= 1;
+       }
+
+       if (bufferMaxIndex < 2) {
+               *count = 0;
+               return KERN_RESOURCE_SHORTAGE;
+       }
+
+       currPC = (uint64_t)state->pc; /* r15 */
+       if (state->cpsr & PSR_TF)
+               currPC |= 1ULL; /* encode thumb mode into low bit of PC */
+
+       currLR = (uint64_t)state->lr; /* r14 */
+       currSP = (uint64_t)state->sp; /* r13 */
+
+       fp = (uint32_t *)state->r[7]; /* frame pointer */
+       topfp = fp;
+
+       bufferIndex = 0;  // start with a stack of size zero
+       buffer[bufferIndex++] = chudxnu_vm_unslide(currPC, supervisor); // save PC in position 0.
+
+       // Now, fill buffer with stack backtraces.
+       while (bufferIndex < bufferMaxIndex) {
+               pc = 0ULL;
+               /*
+                * Below the frame pointer, the following values are saved:
+                * -> FP
+                */
+
+               /*
+                * Note that we read the pc even for the first stack frame
+                * (which, in theory, is always empty because the callee fills
+                * it in just before it lowers the stack.  However, if we
+                * catch the program in between filling in the return address
+                * and lowering the stack, we want to still have a valid
+                * backtrace. FixupStack correctly disregards this value if
+                * necessary.
+                */
+
+               if((uint32_t)fp == 0 || ((uint32_t)fp & 0x3) != 0) {
+                       /* frame pointer is invalid - stop backtracing */
+                       pc = 0ULL;
+                       break;
+               }
+
+               if (supervisor) {
+                       if (((uint32_t)fp > kernStackMax) ||
+                           ((uint32_t)fp < kernStackMin)) {
+                               kr = KERN_FAILURE;
+                       } else {
+                               kr = chudxnu_kern_read(&frame,
+                                               (vm_offset_t)fp,
+                                               (vm_size_t)sizeof(frame));
+                               if (kr == KERN_SUCCESS) {
+                                       pc = (uint64_t)frame[1];
+                                       nextFramePointer = (uint32_t *) (frame[0]);
+                               } else {
+                                       pc = 0ULL;
+                                       nextFramePointer = 0ULL;
+                                       kr = KERN_FAILURE;
+                               }
+                       }
+               } else {
+                       kr = chudxnu_task_read(task,
+                                               &frame,
+                                               (((uint64_t)(uint32_t)fp) & 0x00000000FFFFFFFFULL),
+                                               sizeof(frame));
+                       if (kr == KERN_SUCCESS) {
+                               pc = (uint64_t) frame[1];
+                               nextFramePointer = (uint32_t *) (frame[0]);
+                       } else {
+                               pc = 0ULL;
+                               nextFramePointer = 0ULL;
+                               kr = KERN_FAILURE;
+                       }
+               }
+
+               if (kr != KERN_SUCCESS) {
+                       pc = 0ULL;
+                       break;
+               }
+
+               if (nextFramePointer) {
+                       buffer[bufferIndex++] = chudxnu_vm_unslide(pc, supervisor);
+                       prevPC = pc;
+               }
+
+               if (nextFramePointer < fp)
+                       break;
+               else
+                       fp = nextFramePointer;
+       }
+
+       if (bufferIndex >= bufferMaxIndex) {
+               bufferIndex = bufferMaxIndex;
+               kr = KERN_RESOURCE_SHORTAGE;
+       } else {
+               kr = KERN_SUCCESS;
+       }
+
+       // Save link register and R13 (sp) at bottom of stack (used for later fixup).
+       buffer[bufferIndex++] = chudxnu_vm_unslide(currLR, supervisor);
+       if( flags & CS_FLAG_EXTRASP )
+               buffer[bufferIndex++] = chudxnu_vm_unslide(currSP, supervisor);
+
+       *count = bufferIndex;
+       return kr;
+
+
+}
+
+kern_return_t
+chudxnu_thread_get_callstack64_kperf(
+       thread_t                thread,
+       uint64_t                *callStack,
+       mach_msg_type_number_t  *count,
+       boolean_t               user_only)
+{
+       return chudxnu_thread_get_callstack64_internal( thread, callStack, count, user_only, 0 );
+}
+#elif __arm64__
+// chudxnu_thread_get_callstack gathers a raw callstack along with any information needed to
+// fix it up later (in case we stopped program as it was saving values into prev stack frame, etc.)
+// after sampling has finished.
+//
+// For an N-entry callstack:
+//
+// [0]      current pc
+// [1..N-3] stack frames (including current one)
+// [N-2]    current LR (return value if we're in a leaf function)
+// [N-1]    current r0 (in case we've saved LR in r0) (optional)
+//
+//
+#define ARM_SUPERVISOR_MODE(cpsr) ((((cpsr) & PSR_MODE_MASK) != PSR_USER_MODE) ? TRUE : FALSE)
+
+#define CS_FLAG_EXTRASP  1  // capture extra sp register
+
+static kern_return_t
+chudxnu_thread_get_callstack64_internal(
+       thread_t                thread,
+       uint64_t                *callStack,
+       mach_msg_type_number_t  *count,
+       boolean_t               user_only,
+       int flags)
+{
+       kern_return_t   kr = KERN_SUCCESS;
+       task_t                  task;
+       uint64_t                currPC=0ULL, currLR=0ULL, currSP=0ULL;
+       uint64_t                prevPC = 0ULL;
+       uint64_t                kernStackMin = thread->kernel_stack;
+       uint64_t                kernStackMax = kernStackMin + kernel_stack_size;
+       uint64_t       *buffer = callStack;
+       int             bufferIndex = 0;
+       int             bufferMaxIndex = 0;
+       boolean_t       kernel = FALSE;
+       struct arm_saved_state *sstate = NULL;
+       uint64_t                pc = 0ULL;
+
+       task = get_threadtask(thread);
+       bufferMaxIndex = *count;
+       //get thread state
+       if (user_only)
+               sstate = find_user_regs(thread);
+       else
+               sstate = find_kern_regs(thread);
+
+       if (!sstate) {
+               *count = 0; 
+               return KERN_FAILURE;
+       }
+
+       if (is_saved_state64(sstate)) {
+               struct arm_saved_state64 *state = NULL;
+               uint64_t *fp=NULL, *nextFramePointer=NULL, *topfp=NULL;
+               uint64_t frame[2];
+
+               state = saved_state64(sstate);
+
+               /* make sure it is safe to dereference before you do it */
+               kernel = PSR64_IS_KERNEL(state->cpsr);
+
+               /* can't take a kernel callstack if we've got a user frame */
+               if( !user_only && !kernel )
+                       return KERN_FAILURE;
+
+               /*
+                * Reserve space for saving LR (and sometimes SP) at the end of the
+                * backtrace.
+                */
+               if (flags & CS_FLAG_EXTRASP) {
+                       bufferMaxIndex -= 2;
+               } else {
+                       bufferMaxIndex -= 1;
+               }
+
+               if (bufferMaxIndex < 2) {
+                       *count = 0;
+                       return KERN_RESOURCE_SHORTAGE;
+               }
+
+               currPC = state->pc;
+               currLR = state->lr;
+               currSP = state->sp;
+
+               fp = (uint64_t *)state->fp; /* frame pointer */
+               topfp = fp;
+
+               bufferIndex = 0;  // start with a stack of size zero
+               buffer[bufferIndex++] = chudxnu_vm_unslide(currPC, kernel); // save PC in position 0.
+
+               BUF_VERB(PERF_CS_BACKTRACE | DBG_FUNC_START, kernel, 0);
+
+               // Now, fill buffer with stack backtraces.
+               while (bufferIndex < bufferMaxIndex) {
+                       pc = 0ULL;
+                       /*
+                        * Below the frame pointer, the following values are saved:
+                        * -> FP
+                        */
+
+                       /*
+                        * Note that we read the pc even for the first stack frame
+                        * (which, in theory, is always empty because the callee fills
+                        * it in just before it lowers the stack.  However, if we
+                        * catch the program in between filling in the return address
+                        * and lowering the stack, we want to still have a valid
+                        * backtrace. FixupStack correctly disregards this value if
+                        * necessary.
+                        */
+
+                       if((uint64_t)fp == 0 || ((uint64_t)fp & 0x3) != 0) {
+                               /* frame pointer is invalid - stop backtracing */
+                               pc = 0ULL;
+                               break;
+                       }
+
+                       if (kernel) {
+                               if (((uint64_t)fp > kernStackMax) ||
+                                   ((uint64_t)fp < kernStackMin)) {
+                                       kr = KERN_FAILURE;
+                               } else {
+                                       kr = chudxnu_kern_read(&frame,
+                                                       (vm_offset_t)fp,
+                                                       (vm_size_t)sizeof(frame));
+                                       if (kr == KERN_SUCCESS) {
+                                               pc = frame[1];
+                                               nextFramePointer = (uint64_t *)frame[0];
+                                       } else {
+                                               pc = 0ULL;
+                                               nextFramePointer = 0ULL;
+                                               kr = KERN_FAILURE;
+                                       }
+                               }
+                       } else {
+                               kr = chudxnu_task_read(task,
+                                                       &frame,
+                                                       (vm_offset_t)fp,
+                                                       (vm_size_t)sizeof(frame));
+                               if (kr == KERN_SUCCESS) {
+                                       pc = frame[1];
+                                       nextFramePointer = (uint64_t *)(frame[0]);
+                               } else {
+                                       pc = 0ULL;
+                                       nextFramePointer = 0ULL;
+                                       kr = KERN_FAILURE;
+                               }
+                       }
+
+                       if (kr != KERN_SUCCESS) {
+                               pc = 0ULL;
+                               break;
+                       }
+
+                       if (nextFramePointer) {
+                               buffer[bufferIndex++] = chudxnu_vm_unslide(pc, kernel);
+                               prevPC = pc;
+                       }
+
+                       if (nextFramePointer < fp)
+                               break;
+                       else
+                               fp = nextFramePointer;
+               }
+
+               BUF_VERB(PERF_CS_BACKTRACE | DBG_FUNC_END, bufferIndex);
+
+               if (bufferIndex >= bufferMaxIndex) {
+                       bufferIndex = bufferMaxIndex;
+                       kr = KERN_RESOURCE_SHORTAGE;
+               } else {
+                       kr = KERN_SUCCESS;
+               }
+
+               // Save link register and SP at bottom of stack (used for later fixup).
+               buffer[bufferIndex++] = chudxnu_vm_unslide(currLR, kernel);
+               if( flags & CS_FLAG_EXTRASP )
+                       buffer[bufferIndex++] = chudxnu_vm_unslide(currSP, kernel);     
+       } else {
+               struct arm_saved_state32 *state = NULL;
+               uint32_t *fp=NULL, *nextFramePointer=NULL, *topfp=NULL;
+
+               /* 64-bit kernel stacks, 32-bit user stacks */
+               uint64_t frame[2];
+               uint32_t frame32[2];
+       
+               state = saved_state32(sstate);
+
+               /* make sure it is safe to dereference before you do it */
+               kernel = ARM_SUPERVISOR_MODE(state->cpsr);
+
+               /* can't take a kernel callstack if we've got a user frame */
+               if( !user_only && !kernel )
+                       return KERN_FAILURE;
+
+               /*
+                * Reserve space for saving LR (and sometimes SP) at the end of the
+                * backtrace.
+                */
+               if (flags & CS_FLAG_EXTRASP) {
+                       bufferMaxIndex -= 2;
+               } else {
+                       bufferMaxIndex -= 1;
+               }
+
+               if (bufferMaxIndex < 2) {
+                       *count = 0;
+                       return KERN_RESOURCE_SHORTAGE;
+               }
+
+               currPC = (uint64_t)state->pc; /* r15 */
+               if (state->cpsr & PSR_TF)
+                       currPC |= 1ULL; /* encode thumb mode into low bit of PC */
+
+               currLR = (uint64_t)state->lr; /* r14 */
+               currSP = (uint64_t)state->sp; /* r13 */
+
+               fp = (uint32_t *)(uintptr_t)state->r[7]; /* frame pointer */
+               topfp = fp;
+
+               bufferIndex = 0;  // start with a stack of size zero
+               buffer[bufferIndex++] = chudxnu_vm_unslide(currPC, kernel); // save PC in position 0.
+
+               BUF_VERB(PERF_CS_BACKTRACE | DBG_FUNC_START, kernel, 1);
+
+               // Now, fill buffer with stack backtraces.
+               while (bufferIndex < bufferMaxIndex) {
+                       pc = 0ULL;
+                       /*
+                        * Below the frame pointer, the following values are saved:
+                        * -> FP
+                        */
+
+                       /*
+                        * Note that we read the pc even for the first stack frame
+                        * (which, in theory, is always empty because the callee fills
+                        * it in just before it lowers the stack.  However, if we
+                        * catch the program in between filling in the return address
+                        * and lowering the stack, we want to still have a valid
+                        * backtrace. FixupStack correctly disregards this value if
+                        * necessary.
+                        */
+
+                       if((uint32_t)fp == 0 || ((uint32_t)fp & 0x3) != 0) {
+                               /* frame pointer is invalid - stop backtracing */
+                               pc = 0ULL;
+                               break;
+                       }
+
+                       if (kernel) {
+                               if (((uint32_t)fp > kernStackMax) ||
+                                   ((uint32_t)fp < kernStackMin)) {
+                                       kr = KERN_FAILURE;
+                               } else {
+                                       kr = chudxnu_kern_read(&frame,
+                                                       (vm_offset_t)fp,
+                                                       (vm_size_t)sizeof(frame));
+                                       if (kr == KERN_SUCCESS) {
+                                               pc = (uint64_t)frame[1];
+                                               nextFramePointer = (uint32_t *) (frame[0]);
+                                       } else {
+                                               pc = 0ULL;
+                                               nextFramePointer = 0ULL;
+                                               kr = KERN_FAILURE;
+                                       }
+                               }
+                       } else {
+                               kr = chudxnu_task_read(task,
+                                                       &frame32,
+                                                       (((uint64_t)(uint32_t)fp) & 0x00000000FFFFFFFFULL),
+                                                       sizeof(frame32));
+                               if (kr == KERN_SUCCESS) {
+                                       pc = (uint64_t)frame32[1];
+                                       nextFramePointer = (uint32_t *)(uintptr_t)(frame32[0]);
+                               } else {
+                                       pc = 0ULL;
+                                       nextFramePointer = 0ULL;
+                                       kr = KERN_FAILURE;
+                               }
+                       }
+
+                       if (kr != KERN_SUCCESS) {
+                               pc = 0ULL;
+                               break;
+                       }
+
+                       if (nextFramePointer) {
+                               buffer[bufferIndex++] = chudxnu_vm_unslide(pc, kernel);
+                               prevPC = pc;
+                       }
+
+                       if (nextFramePointer < fp)
+                               break;
+                       else
+                               fp = nextFramePointer;
+               }
+
+               BUF_VERB(PERF_CS_BACKTRACE | DBG_FUNC_END, bufferIndex);
+
+               /* clamp callstack size to max */
+               if (bufferIndex >= bufferMaxIndex) {
+                       bufferIndex = bufferMaxIndex;
+                       kr = KERN_RESOURCE_SHORTAGE;
+               } else {
+                       /* ignore all other failures */
+                       kr = KERN_SUCCESS;
+               }
+
+               // Save link register and R13 (sp) at bottom of stack (used for later fixup).
+               buffer[bufferIndex++] = chudxnu_vm_unslide(currLR, kernel);
+               if( flags & CS_FLAG_EXTRASP )
+                       buffer[bufferIndex++] = chudxnu_vm_unslide(currSP, kernel);
+       }
+
+       *count = bufferIndex;
+       return kr;
+}
+
+kern_return_t
+chudxnu_thread_get_callstack64_kperf(
+       thread_t                thread,
+       uint64_t                *callStack,
+       mach_msg_type_number_t  *count,
+       boolean_t               user_only)
+{
+       return chudxnu_thread_get_callstack64_internal( thread, callStack, count, user_only, 0 );
+}
+#elif __x86_64__
+
+#define VALID_STACK_ADDRESS(supervisor, addr, minKernAddr, maxKernAddr)   (supervisor ? (addr>=minKernAddr && addr<=maxKernAddr) : TRUE)
+// don't try to read in the hole
+#define VALID_STACK_ADDRESS64(supervisor, addr, minKernAddr, maxKernAddr) \
+(supervisor ? ((uint64_t)addr >= minKernAddr && (uint64_t)addr <= maxKernAddr) : \
+((uint64_t)addr != 0ULL && ((uint64_t)addr <= 0x00007FFFFFFFFFFFULL || (uint64_t)addr >= 0xFFFF800000000000ULL)))
+
+typedef struct _cframe64_t {
+       uint64_t        prevFP;         // can't use a real pointer here until we're a 64 bit kernel
+       uint64_t        caller;
+       uint64_t        args[0];
+}cframe64_t;
+
+
+typedef struct _cframe_t {
+       uint32_t                prev;   // this is really a user32-space pointer to the previous frame
+       uint32_t                caller;
+       uint32_t                args[0];
+} cframe_t;
+
+extern void * find_user_regs(thread_t);
+extern x86_saved_state32_t *find_kern_regs(thread_t);
+
+static kern_return_t do_kernel_backtrace(
+       thread_t thread,
+       struct x86_kernel_state *regs, 
+       uint64_t *frames,
+       mach_msg_type_number_t *start_idx,
+       mach_msg_type_number_t max_idx)
+{
+       uint64_t kernStackMin = (uint64_t)thread->kernel_stack;
+    uint64_t kernStackMax = (uint64_t)kernStackMin + kernel_stack_size;
+       mach_msg_type_number_t ct = *start_idx;
+       kern_return_t kr = KERN_FAILURE;
+
+#if __LP64__
+       uint64_t currPC = 0ULL;
+       uint64_t currFP = 0ULL;
+       uint64_t prevPC = 0ULL;
+       uint64_t prevFP = 0ULL;
+       if(KERN_SUCCESS != chudxnu_kern_read(&currPC, (vm_offset_t)&(regs->k_rip), sizeof(uint64_t))) {
+               return KERN_FAILURE;
+       }
+       if(KERN_SUCCESS != chudxnu_kern_read(&currFP, (vm_offset_t)&(regs->k_rbp), sizeof(uint64_t))) {
+               return KERN_FAILURE;
+       }
+#else
+       uint32_t currPC = 0U;
+       uint32_t currFP = 0U;
+       uint32_t prevPC = 0U;
+       uint32_t prevFP = 0U;
+       if(KERN_SUCCESS != chudxnu_kern_read(&currPC, (vm_offset_t)&(regs->k_eip), sizeof(uint32_t))) {
+               return KERN_FAILURE;
+       }
+       if(KERN_SUCCESS != chudxnu_kern_read(&currFP, (vm_offset_t)&(regs->k_ebp), sizeof(uint32_t))) {
+               return KERN_FAILURE;
+       }
+#endif
+
+       if(*start_idx >= max_idx)
+               return KERN_RESOURCE_SHORTAGE;  // no frames traced
+       
+       if(!currPC) {
+               return KERN_FAILURE;
+       }
+
+       frames[ct++] = chudxnu_vm_unslide((uint64_t)currPC, 1);
+
+       // build a backtrace of this kernel state
+#if __LP64__
+       while(VALID_STACK_ADDRESS64(TRUE, currFP, kernStackMin, kernStackMax)) {
+               // this is the address where caller lives in the user thread
+               uint64_t caller = currFP + sizeof(uint64_t);
+#else
+       while(VALID_STACK_ADDRESS(TRUE, currFP, kernStackMin, kernStackMax)) {
+               uint32_t caller = (uint32_t)currFP + sizeof(uint32_t);
+#endif
+
+        if(!currFP || !currPC) {
+            currPC = 0;
+            break;
+        }
+
+        if(ct >= max_idx) {
+                       *start_idx = ct;
+            return KERN_RESOURCE_SHORTAGE;
+        }
+
+               /* read our caller */
+               kr = chudxnu_kern_read(&currPC, (vm_offset_t)caller, sizeof(currPC));
+
+               if(kr != KERN_SUCCESS || !currPC) {
+                       currPC = 0UL;
+                       break;
+               }
+
+        /* 
+         * retrive contents of the frame pointer and advance to the next stack
+         * frame if it's valid 
+         */
+        prevFP = 0;
+               kr = chudxnu_kern_read(&prevFP, (vm_offset_t)currFP, sizeof(currPC));
+
+#if __LP64__
+        if(VALID_STACK_ADDRESS64(TRUE, prevFP, kernStackMin, kernStackMax)) {
+#else
+        if(VALID_STACK_ADDRESS(TRUE, prevFP, kernStackMin, kernStackMax)) {
+#endif
+            frames[ct++] = chudxnu_vm_unslide((uint64_t)currPC, 1);
+            prevPC = currPC;
+        }
+        if(prevFP <= currFP) {
+            break;
+        } else {
+            currFP = prevFP;
+        }      
+       }
+
+       *start_idx = ct;
+       return KERN_SUCCESS;
+}
+
+
+
+static kern_return_t do_backtrace32(
+       task_t task,
+       thread_t thread,
+       x86_saved_state32_t *regs, 
+       uint64_t *frames,
+       mach_msg_type_number_t *start_idx,
+       mach_msg_type_number_t max_idx,
+       boolean_t supervisor)
+{
+       uint32_t tmpWord = 0UL;
+       uint64_t currPC = (uint64_t) regs->eip;
+       uint64_t currFP = (uint64_t) regs->ebp;
+       uint64_t prevPC = 0ULL;
+       uint64_t prevFP = 0ULL;
+       uint64_t kernStackMin = thread->kernel_stack;
+    uint64_t kernStackMax = kernStackMin + kernel_stack_size;
+       mach_msg_type_number_t ct = *start_idx;
+       kern_return_t kr = KERN_FAILURE;
+
+       if(ct >= max_idx)
+               return KERN_RESOURCE_SHORTAGE;  // no frames traced
+       
+       frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
+
+       // build a backtrace of this 32 bit state.
+       while(VALID_STACK_ADDRESS(supervisor, currFP, kernStackMin, kernStackMax)) {
+               cframe_t *fp = (cframe_t *) (uintptr_t) currFP;
+
+        if(!currFP) {
+            currPC = 0;
+            break;
+        }
+
+        if(ct >= max_idx) {
+                       *start_idx = ct;
+            return KERN_RESOURCE_SHORTAGE;
+        }
+
+               /* read our caller */
+               if(supervisor) {
+                       kr = chudxnu_kern_read(&tmpWord, (vm_offset_t) &fp->caller, sizeof(uint32_t));
+               } else {
+                       kr = chudxnu_task_read(task, &tmpWord, (vm_offset_t) &fp->caller, sizeof(uint32_t));
+               }
+
+               if(kr != KERN_SUCCESS) {
+                       currPC = 0ULL;
+                       break;
+               }
+
+               currPC = (uint64_t) tmpWord;    // promote 32 bit address
+
+        /* 
+         * retrive contents of the frame pointer and advance to the next stack
+         * frame if it's valid 
+         */
+        prevFP = 0;
+               if(supervisor) {
+                       kr = chudxnu_kern_read(&tmpWord, (vm_offset_t)&fp->prev, sizeof(uint32_t));
+               } else {
+                       kr = chudxnu_task_read(task, &tmpWord, (vm_offset_t)&fp->prev, sizeof(uint32_t));
+               }
+               prevFP = (uint64_t) tmpWord;    // promote 32 bit address
+
+        if(prevFP) {
+            frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
+            prevPC = currPC;
+        }
+        if(prevFP < currFP) {
+            break;
+        } else {
+            currFP = prevFP;
+        }      
+       }
+
+       *start_idx = ct;
+       return KERN_SUCCESS;
+}
+
+static kern_return_t do_backtrace64(
+       task_t task,
+       thread_t thread,
+       x86_saved_state64_t *regs, 
+       uint64_t *frames,
+       mach_msg_type_number_t *start_idx,
+       mach_msg_type_number_t max_idx,
+       boolean_t supervisor)
+{
+       uint64_t currPC = regs->isf.rip;
+       uint64_t currFP = regs->rbp;
+       uint64_t prevPC = 0ULL;
+       uint64_t prevFP = 0ULL;
+       uint64_t kernStackMin = (uint64_t)thread->kernel_stack;
+    uint64_t kernStackMax = (uint64_t)kernStackMin + kernel_stack_size;
+       mach_msg_type_number_t ct = *start_idx;
+       kern_return_t kr = KERN_FAILURE;
+
+       if(*start_idx >= max_idx)
+               return KERN_RESOURCE_SHORTAGE;  // no frames traced
+       
+       frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
+
+       // build a backtrace of this 32 bit state.
+       while(VALID_STACK_ADDRESS64(supervisor, currFP, kernStackMin, kernStackMax)) {
+               // this is the address where caller lives in the user thread
+               uint64_t caller = currFP + sizeof(uint64_t);
+
+        if(!currFP) {
+            currPC = 0;
+            break;
+        }
+
+        if(ct >= max_idx) {
+                       *start_idx = ct;
+            return KERN_RESOURCE_SHORTAGE;
+        }
+
+               /* read our caller */
+               if(supervisor) {
+                       kr = chudxnu_kern_read(&currPC, (vm_offset_t)caller, sizeof(uint64_t));
+               } else {
+                       kr = chudxnu_task_read(task, &currPC, caller, sizeof(uint64_t));
+               }
+
+               if(kr != KERN_SUCCESS) {
+                       currPC = 0ULL;
+                       break;
+               }
+
+        /* 
+         * retrive contents of the frame pointer and advance to the next stack
+         * frame if it's valid 
+         */
+        prevFP = 0;
+               if(supervisor) {
+                       kr = chudxnu_kern_read(&prevFP, (vm_offset_t)currFP, sizeof(uint64_t));
+               } else {
+                       kr = chudxnu_task_read(task, &prevFP, currFP, sizeof(uint64_t));
+               }
+
+        if(VALID_STACK_ADDRESS64(supervisor, prevFP, kernStackMin, kernStackMax)) {
+            frames[ct++] = chudxnu_vm_unslide(currPC, supervisor);
+            prevPC = currPC;
+        }
+        if(prevFP < currFP) {
+            break;
+        } else {
+            currFP = prevFP;
+        }      
+       }
+
+       *start_idx = ct;
+       return KERN_SUCCESS;
+}
+
+static kern_return_t
+chudxnu_thread_get_callstack64_internal(
+       thread_t                thread,
+       uint64_t                *callstack,
+       mach_msg_type_number_t  *count,
+       boolean_t               user_only,
+       boolean_t               kern_only)
+{
+       kern_return_t kr = KERN_FAILURE;
+    task_t task = thread->task;
+    uint64_t currPC = 0ULL;
+       boolean_t supervisor = FALSE;
+    mach_msg_type_number_t bufferIndex = 0;
+    mach_msg_type_number_t bufferMaxIndex = *count;
+       x86_saved_state_t *tagged_regs = NULL;          // kernel register state
+       x86_saved_state64_t *regs64 = NULL;
+       x86_saved_state32_t *regs32 = NULL;
+       x86_saved_state32_t *u_regs32 = NULL;
+       x86_saved_state64_t *u_regs64 = NULL;
+       struct x86_kernel_state *kregs = NULL;
+
+       if(ml_at_interrupt_context()) {
+               
+               if(user_only) {
+                       /* can't backtrace user state on interrupt stack. */
+                       return KERN_FAILURE;
+               }
+
+               /* backtracing at interrupt context? */
+                if(thread == current_thread() && current_cpu_datap()->cpu_int_state) {
+                       /* 
+                        * Locate the registers for the interrupted thread, assuming it is
+                        * current_thread(). 
+                        */
+                       tagged_regs = current_cpu_datap()->cpu_int_state;
+                       
+                       if(is_saved_state64(tagged_regs)) {
+                               /* 64 bit registers */
+                               regs64 = saved_state64(tagged_regs);
+                               supervisor = ((regs64->isf.cs & SEL_PL) != SEL_PL_U);
+                       } else {
+                               /* 32 bit registers */
+                               regs32 = saved_state32(tagged_regs);
+                               supervisor = ((regs32->cs & SEL_PL) != SEL_PL_U);
+                       }
+               } 
+       }
+
+       if(!ml_at_interrupt_context() && kernel_task == task) {
+
+               if(!thread->kernel_stack) {
+                       return KERN_FAILURE;
+               }
+
+               // Kernel thread not at interrupt context
+               kregs = (struct x86_kernel_state *)NULL;
+
+               // nofault read of the thread->kernel_stack pointer
+               if(KERN_SUCCESS != chudxnu_kern_read(&kregs, (vm_offset_t)&(thread->kernel_stack), sizeof(void *))) {
+                       return KERN_FAILURE;
+               }
+
+               // Adjust to find the saved kernel state
+               kregs = STACK_IKS((vm_offset_t)(uintptr_t)kregs);
+
+               supervisor = TRUE;
+       } else if(!tagged_regs) {
+               /* 
+                * not at interrupt context, or tracing a different thread than
+                * current_thread() at interrupt context 
+                */
+               tagged_regs = USER_STATE(thread);
+               if(is_saved_state64(tagged_regs)) {
+                       /* 64 bit registers */
+                       regs64 = saved_state64(tagged_regs);
+                       supervisor = ((regs64->isf.cs & SEL_PL) != SEL_PL_U); 
+               } else {
+                       /* 32 bit registers */
+                       regs32 = saved_state32(tagged_regs);
+                       supervisor = ((regs32->cs & SEL_PL) != SEL_PL_U);
+               }
+       }
+
+       *count = 0; 
+
+       if(supervisor) {
+               // the caller only wants a user callstack.
+               if(user_only) {
+                       // bail - we've only got kernel state
+                       return KERN_FAILURE;
+               }
+       } else {
+               // regs32(64) is not in supervisor mode.
+               u_regs32 = regs32;
+               u_regs64 = regs64;
+               regs32 = NULL;
+               regs64 = NULL;
+       }
+
+       if (user_only) {
+               /* we only want to backtrace the user mode */
+               if(!(u_regs32 || u_regs64)) {
+                       /* no user state to look at */
+                       return KERN_FAILURE;
+               }
+       }
+
+       /* 
+        * Order of preference for top of stack:
+        * 64 bit kernel state (not likely)
+        * 32 bit kernel state
+        * 64 bit user land state
+        * 32 bit user land state
+        */
+
+       if(kregs) {
+               /*
+                * nofault read of the registers from the kernel stack (as they can
+                * disappear on the fly).
+                */
+
+               if(KERN_SUCCESS != chudxnu_kern_read(&currPC, (vm_offset_t)&(kregs->k_rip), sizeof(uint64_t))) {
+                       return KERN_FAILURE;
+               }
+       } else if(regs64) {
+               currPC = regs64->isf.rip;
+       } else if(regs32) {
+               currPC = (uint64_t) regs32->eip;
+       } else if(u_regs64) {
+               currPC = u_regs64->isf.rip;
+       } else if(u_regs32) {
+               currPC = (uint64_t) u_regs32->eip;
+       }
+       
+       if(!currPC) {
+               /* no top of the stack, bail out */
+               return KERN_FAILURE;
+       }
+
+       bufferIndex = 0;
+               
+       if(bufferMaxIndex < 1) {
+               *count = 0;
+               return KERN_RESOURCE_SHORTAGE;
+       }
+
+       /* backtrace kernel */
+       if(kregs) {
+               addr64_t address = 0ULL;
+               size_t size = 0UL;
+
+               // do the backtrace
+               kr = do_kernel_backtrace(thread, kregs, callstack, &bufferIndex, bufferMaxIndex);
+
+               // and do a nofault read of (r|e)sp
+               uint64_t rsp = 0ULL;
+               size = sizeof(uint64_t);
+               
+               if(KERN_SUCCESS != chudxnu_kern_read(&address, (vm_offset_t)&(kregs->k_rsp), size)) {
+                       address = 0ULL;
+               }
+
+               if(address && KERN_SUCCESS == chudxnu_kern_read(&rsp, (vm_offset_t)address, size) && bufferIndex < bufferMaxIndex) {
+                       callstack[bufferIndex++] = (uint64_t)rsp;
+               }
+       } else if(regs64) {
+               uint64_t rsp = 0ULL;
+
+               // backtrace the 64bit side.
+               kr = do_backtrace64(task, thread, regs64, callstack, &bufferIndex,
+                                   bufferMaxIndex - 1, TRUE);
+
+               if(KERN_SUCCESS == chudxnu_kern_read(&rsp, (vm_offset_t) regs64->isf.rsp, sizeof(uint64_t)) && 
+                       bufferIndex < bufferMaxIndex) {
+                       callstack[bufferIndex++] = rsp;
+               }
+
+       } else if(regs32) {
+               uint32_t esp = 0UL;
+
+               // backtrace the 32bit side.
+               kr = do_backtrace32(task, thread, regs32, callstack, &bufferIndex,
+                                   bufferMaxIndex - 1, TRUE);
+               
+               if(KERN_SUCCESS == chudxnu_kern_read(&esp, (vm_offset_t) regs32->uesp, sizeof(uint32_t)) && 
+                       bufferIndex < bufferMaxIndex) {
+                       callstack[bufferIndex++] = (uint64_t) esp;
+               }
+       } else if(u_regs64 && !kern_only) {
+               /* backtrace user land */
+               uint64_t rsp = 0ULL;
+               
+               kr = do_backtrace64(task, thread, u_regs64, callstack, &bufferIndex,
+                                   bufferMaxIndex - 1, FALSE);
+
+               if(KERN_SUCCESS == chudxnu_task_read(task, &rsp, (addr64_t) u_regs64->isf.rsp, sizeof(uint64_t)) && 
+                       bufferIndex < bufferMaxIndex) {
+                       callstack[bufferIndex++] = rsp;
+               }
+
+       } else if(u_regs32 && !kern_only) {
+               uint32_t esp = 0UL;
+               
+               kr = do_backtrace32(task, thread, u_regs32, callstack, &bufferIndex,
+                                   bufferMaxIndex - 1, FALSE);
+
+               if(KERN_SUCCESS == chudxnu_task_read(task, &esp, (addr64_t) u_regs32->uesp, sizeof(uint32_t)) && 
+                       bufferIndex < bufferMaxIndex) {
+                       callstack[bufferIndex++] = (uint64_t) esp;
+               }
+       }
+
+    *count = bufferIndex;
+    return kr;
+}
+
+__private_extern__
+kern_return_t chudxnu_thread_get_callstack64_kperf(
+       thread_t                thread,
+       uint64_t                *callstack,
+       mach_msg_type_number_t  *count,
+       boolean_t               is_user)
+{
+       return chudxnu_thread_get_callstack64_internal(thread, callstack, count, is_user, !is_user);
+}
+#else /* !__arm__ && !__arm64__ && !__x86_64__ */
+#error kperf: unsupported architecture
+#endif /* !__arm__ && !__arm64__ && !__x86_64__ */
index a6cf3c2e333b3d9a69a7bb86f8a45a503cbe9521..86ed35d8711638d55de4a80599e1654dce7e77f4 100644 (file)
@@ -105,8 +105,6 @@ static void
 kperf_sample_cpu(struct kperf_timer *timer, bool system_sample,
                bool only_system)
 {
-       struct kperf_context ctx;
-
        assert(timer != NULL);
 
        /* Always cut a tracepoint to show a sample event occurred */
@@ -115,15 +113,18 @@ kperf_sample_cpu(struct kperf_timer *timer, bool system_sample,
        int ncpu = cpu_number();
 
        struct kperf_sample *intbuf = kperf_intr_sample_buffer();
+#if DEVELOPMENT || DEBUG
+       intbuf->sample_time = mach_absolute_time();
+#endif /* DEVELOPMENT || DEBUG */
 
        /* On a timer, we can see the "real" current thread */
-       ctx.cur_thread = current_thread();
+       struct kperf_context ctx = {
+               .cur_thread = current_thread(),
+               .trigger_type = TRIGGER_TYPE_TIMER,
+               .trigger_id = (unsigned int)(timer - kperf_timerv),
+       };
        ctx.cur_pid = task_pid(get_threadtask(ctx.cur_thread));
 
-       /* who fired */
-       ctx.trigger_type = TRIGGER_TYPE_TIMER;
-       ctx.trigger_id = (unsigned int)(timer - kperf_timerv);
-
        if (ctx.trigger_id == pet_timer_id && ncpu < machine_info.logical_cpu_max) {
                kperf_tid_on_cpus[ncpu] = thread_tid(ctx.cur_thread);
        }
@@ -169,6 +170,9 @@ kperf_timer_handler(void *param0, __unused void *param1)
        }
 
        timer->active = 1;
+#if DEVELOPMENT || DEBUG
+       timer->fire_time = mach_absolute_time();
+#endif /* DEVELOPMENT || DEBUG */
 
        /* along the lines of do not ipi if we are all shutting down */
        if (kperf_sampling_status() == KPERF_SAMPLING_SHUTDOWN) {
index 946cc21c0ff56c3439fc3d84a3257d784daf291b..fcc64221720fd60f940a51c4af6e1746d9ce0aac 100644 (file)
@@ -45,6 +45,10 @@ struct kperf_timer {
         * timers.
         */
        bitmap_t pending_cpus;
+
+#if DEVELOPMENT || DEBUG
+       uint64_t fire_time;
+#endif /* DEVELOPMENT || DEBUG */
 };
 
 extern struct kperf_timer *kperf_timerv;
index 35175294f9f55f5f1c10df37b880293591837d3d..35e186ebbd94189d1935c2c126514416c1fa1492 100644 (file)
@@ -49,7 +49,11 @@ struct kperf_sample {
 
 #if KPC
        struct kpcdata    kpcdata;
-#endif
+#endif /* KPC */
+
+#if DEVELOPMENT || DEBUG
+       uint64_t sample_time;
+#endif /* DEVELOPMENT || DEBUG */
 };
 
 /* cache of threads on each CPU during a timer fire */
index e62f8934d2a72f973a13e1d1d8cdb49a7021e389..176520f0c102c412ecc739c0a6b13d1f7e897b9b 100644 (file)
@@ -91,12 +91,12 @@ kperf_thread_info_runmode_legacy(thread_t thread)
                kperf_state |= KPERF_TI_IDLE;
        }
 
-#if !TARGET_OS_EMBEDDED
+#if !CONFIG_EMBEDDED
        /* on desktop, if state is blank, leave not idle set */
        if (kperf_state == 0) {
                return (TH_IDLE << 16);
        }
-#endif /* !TARGET_OS_EMBEDDED */
+#endif /* !CONFIG_EMBEDDED */
 
        /* high two bytes are inverted mask, low two bytes are normal */
        return (((~kperf_state & 0xffff) << 16) | (kperf_state & 0xffff));
index 815aa22d9c28f88ccdee4ca41f23257f18a55d50..9c293a5ce8f11b0f513ee33398d3ed377ff184bf 100644 (file)
@@ -166,6 +166,7 @@ INSTALL_MI_LIST     = \
 # installed into System.framework's PrivateHeaders/mach subdirectory
 PRIVATE_DATAFILES = \
        bootstrap.h \
+       branch_predicates.h \
        coalition.h \
        coalition_notification.defs \
        host_info.h \
index 0882d3e1e1d732e1eb34a332b3b4039a9368a2e4..a551970dc9ce65a1c120cc6f2409de68fe249ec0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -31,5 +31,7 @@
 #define        _MACH_BRANCH_PREDICATES_H
 
 #define        __probable(x)   __builtin_expect(!!((long)(x)), 1L)
+
 #define        __improbable(x) __builtin_expect(!!((long)(x)), 0L)
+
 #endif /* _MACH_BRANCH_PREDICATES_H */
index 40824547e894032a0de05cff724ec9b7baf4d0b4..f7a24ef197f40b697f17ba74c373c92633b5b3c2 100644 (file)
@@ -99,6 +99,8 @@
 
 #define COALITION_NUM_SORT        (6)
 
+#define COALITION_NUM_THREAD_QOS_TYPES   7
+
 /* Coalition Efficiency Interface Support */
 
 /* Flags for coalition efficiency */
@@ -139,6 +141,8 @@ struct coalition_resource_usage {
        uint64_t energy_billed_to_me;
        uint64_t energy_billed_to_others;
        uint64_t cpu_ptime;
+       uint64_t cpu_time_eqos_len;     /* Stores the number of thread QoS types */
+       uint64_t cpu_time_eqos[COALITION_NUM_THREAD_QOS_TYPES];
 };
 
 #ifdef PRIVATE
index 73efdc4f48568fe9ebb929a902393bb746d3aa38..82ed8d003b292ff467072d038e5eb220bff3d29c 100644 (file)
@@ -88,7 +88,7 @@
 #define HOST_KTRACE_BACKGROUND_PORT     (6 + HOST_MAX_SPECIAL_KERNEL_PORT)
 #define HOST_SEATBELT_PORT              (7 + HOST_MAX_SPECIAL_KERNEL_PORT)
 #define HOST_KEXTD_PORT                 (8 + HOST_MAX_SPECIAL_KERNEL_PORT)
-#define HOST_CHUD_PORT                  (9 + HOST_MAX_SPECIAL_KERNEL_PORT)
+#define HOST_LAUNCHCTL_PORT             (9 + HOST_MAX_SPECIAL_KERNEL_PORT)
 #define HOST_UNFREED_PORT              (10 + HOST_MAX_SPECIAL_KERNEL_PORT)
 #define HOST_AMFID_PORT                        (11 + HOST_MAX_SPECIAL_KERNEL_PORT)
 #define HOST_GSSD_PORT                 (12 + HOST_MAX_SPECIAL_KERNEL_PORT)
 #define HOST_MAX_SPECIAL_PORT          HOST_CLOSURED_PORT
                                         /* MAX = last since rdar://19421223 */
 
+/* obsolete name */
+#define HOST_CHUD_PORT HOST_LAUNCHCTL_PORT
+
 /*
  * Special node identifier to always represent the local node.
  */
 #define host_set_kextd_port(host, port)        \
        (host_set_special_port((host), HOST_KEXTD_PORT, (port)))
 
-#define host_get_chud_port(host, port) \
-       (host_get_special_port((host),                  \
-       HOST_LOCAL_NODE, HOST_CHUD_PORT, (port)))
-#define host_set_chud_port(host, port) \
-       (host_set_special_port((host), HOST_CHUD_PORT, (port)))
+#define host_get_launchctl_port(host, port) \
+       (host_get_special_port((host), HOST_LOCAL_NODE, HOST_LAUNCHCTL_PORT, \
+       (port)))
+#define host_set_launchctl_port(host, port) \
+       (host_set_special_port((host), HOST_LAUNCHCTL_PORT, (port)))
+
+#define host_get_chud_port(host, port) host_get_launchctl_port(host, port)
+#define host_set_chud_port(host, port) host_set_launchctl_port(host, port)
 
 #define host_get_unfreed_port(host, port)      \
        (host_get_special_port((host),                  \
index 0f1e2c46d8482ce5082ec0f6abe447627c720d26..5ca0e125e30c1138e9f11182dd909d07776e4f2c 100644 (file)
@@ -352,4 +352,27 @@ routine host_check_multiuser_mode(
 skip;
 #endif // !KERNEL && LIBSYSCALL_INTERFACE
 
+/*
+ * Returns information about a specific zone.
+ * The zone name is passed in via the argument name,
+ * info returns the zone info.
+ */
+routine mach_zone_info_for_zone(
+               host            : host_priv_t;
+               name            : mach_zone_name_t;
+       out     info            : mach_zone_info_t);
+
+#ifdef PRIVATE
+/*
+ * Returns information about the largest zone.
+ * name returns the zone name, info returns the zone info.
+ */
+routine mach_zone_info_for_largest_zone(
+               host            : host_priv_t;
+       out     name            : mach_zone_name_t;
+       out     info            : mach_zone_info_t);
+#else
+skip;
+#endif
+
 /* vim: set ft=c : */
index b06cf4170eace79fec789c13b85a827f14f4be9b..58e4e75549b58122e9911ff68db44f3350e550fa 100644 (file)
@@ -485,6 +485,7 @@ typedef struct task_flags_info * task_flags_info_t;
 
 #ifdef PRIVATE
 struct task_debug_info_internal {
+       integer_t suspend_count; 
        uint64_t ipc_space_size;
 };
 typedef struct task_debug_info_internal *task_debug_info_internal_t;
index 04e7c0ad538e15ac067f3b0f07ada8521d552520..c4ed1d7cdad42fd6bf13139808c122bd13625c69 100644 (file)
@@ -279,6 +279,11 @@ routine purgable_control(
                control         : vm_purgable_t;
        inout   state           : int);
 
+
+routine _map_exec_lockdown(
+               target_task : vm_map_t);
+
+
 #endif /* VM32_SUPPORT */
 
 /* vim: set ft=c : */
index c6bda2cbba5592605e77b2d02254dc9d5a0198f4..7caa92639bf8e55eb53620aa1f0ee6082c571bb4 100644 (file)
@@ -502,4 +502,9 @@ routine PREFIX(vm_purgable_control) (
                control         : vm_purgable_t;
        inout   state           : int);
 
+
+routine vm_map_exec_lockdown(
+               target_task     : vm_map_t);
+
+
 /* vim: set ft=c : */
index fa0560559023e7c83191d7435af39eed6c71c4ec..04fafe640077e5f1a7230ff5dccede0b6926c5d5 100644 (file)
@@ -275,6 +275,9 @@ typedef struct pmap_statistics      *pmap_statistics_t;
  * VM_FLAGS_PURGABLE
  *     Create a purgable VM object for that new VM region.
  *
+ * VM_FLAGS_4GB_CHUNK
+ *     The new VM region will be chunked up into 4GB sized pieces.
+ *
  * VM_FLAGS_NO_PMAP_CHECK
  *     (for DEBUG kernel config only, ignored for other configs)
  *     Do not check that there is no stale pmap mapping for the new VM region.
@@ -294,6 +297,7 @@ typedef struct pmap_statistics      *pmap_statistics_t;
 #define VM_FLAGS_FIXED         0x0000
 #define VM_FLAGS_ANYWHERE      0x0001
 #define VM_FLAGS_PURGABLE      0x0002
+#define VM_FLAGS_4GB_CHUNK     0x0004
 #define VM_FLAGS_RANDOM_ADDR   0x0008
 #define VM_FLAGS_NO_CACHE      0x0010
 #define VM_FLAGS_RESILIENT_CODESIGN    0x0020
@@ -320,6 +324,7 @@ typedef struct pmap_statistics      *pmap_statistics_t;
 #define VM_FLAGS_USER_ALLOCATE (VM_FLAGS_FIXED |               \
                                 VM_FLAGS_ANYWHERE |            \
                                 VM_FLAGS_PURGABLE |            \
+                                VM_FLAGS_4GB_CHUNK |           \
                                 VM_FLAGS_RANDOM_ADDR |         \
                                 VM_FLAGS_NO_CACHE |            \
                                 VM_FLAGS_OVERWRITE |           \
index b4faebbbf7ac86e94396f629a9547dec989f9d95..be15db509c128609ef5e02093057358942ddbc88 100644 (file)
@@ -76,8 +76,8 @@ type mach_zone_name_array_t = array[] of mach_zone_name_t;
 type mach_zone_info_t = struct[8] of uint64_t;
 type mach_zone_info_array_t = array[] of mach_zone_info_t;
 
-type task_zone_info_t = struct[11] of uint64_t;
-type task_zone_info_array_t = array[] of task_zone_info_t;
+type task_zone_info_t = struct[11] of uint64_t;                                /* deprecated */
+type task_zone_info_array_t = array[] of task_zone_info_t;     /* deprecated */
 
 type hash_info_bucket_t = struct[1] of natural_t;
 type hash_info_bucket_array_t = array[] of hash_info_bucket_t;
index c54a4c5b3809f6e0e4a6fcd5b6aefcc8f7cdf062..81bd7badf6f0ba8f1e22be9e738c56563b9bcc52 100644 (file)
@@ -113,11 +113,24 @@ typedef struct mach_zone_info_data {
        uint64_t        mzi_alloc_size; /* size used for more memory */
        uint64_t        mzi_sum_size;   /* sum of all allocs (life of zone) */
        uint64_t        mzi_exhaustible;        /* merely return if empty? */
-       uint64_t        mzi_collectable;        /* garbage collect elements? */
+       uint64_t        mzi_collectable;        /* garbage collect elements? and how much? */
 } mach_zone_info_t;
 
 typedef mach_zone_info_t *mach_zone_info_array_t;
 
+/*
+ * The lowest bit of mzi_collectable indicates whether or not the zone
+ * is collectable by zone_gc(). The higher bits contain the size in bytes
+ * that can be collected.
+ */
+#define GET_MZI_COLLECTABLE_BYTES(val) ((val) >> 1)
+#define GET_MZI_COLLECTABLE_FLAG(val)  ((val) & 1)
+
+#define SET_MZI_COLLECTABLE_BYTES(val, size)   \
+       (val) = ((val) & 1) | ((size) << 1)
+#define SET_MZI_COLLECTABLE_FLAG(val, flag)            \
+       (val) = (flag) ? ((val) | 1) : (val)
+
 typedef struct task_zone_info_data {
        uint64_t        tzi_count;      /* count of elements in use */
        uint64_t        tzi_cur_size;   /* current memory utilization */
index b9d1384210c77a5ea855e9cc92deef816cbcb578..af3985f95ce6a01232588d7080e7c0d5eb590127 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <kern/assert.h>
 #include <kern/host.h>
+#include <kern/ledger.h>
 #include <kern/thread.h>
 #include <kern/ipc_kobject.h>
 
@@ -969,6 +970,7 @@ fill_procregioninfo(task_t task, uint64_t arg, struct proc_regioninfo_internal *
        vm_map_offset_t         start;
        vm_region_extended_info_data_t extended;
        vm_region_top_info_data_t top;
+       boolean_t do_region_footprint;
 
            task_lock(task);
            map = task->map;
@@ -979,15 +981,75 @@ fill_procregioninfo(task_t task, uint64_t arg, struct proc_regioninfo_internal *
            }
            vm_map_reference(map); 
            task_unlock(task);
-           
+
+           do_region_footprint = task_self_region_footprint();
+
            vm_map_lock_read(map);
 
            start = address;
+
            if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
                if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
+                       if (do_region_footprint &&
+                           address == tmp_entry->vme_end) {
+                               ledger_amount_t nonvol, nonvol_compressed;
+
+                               /*
+                                * This request is right after the last valid
+                                * memory region;  instead of reporting the
+                                * end of the address space, report a fake
+                                * memory region to account for non-volatile
+                                * purgeable memory owned by this task.
+                                */
+
+                               ledger_get_balance(
+                                       task->ledger,
+                                       task_ledgers.purgeable_nonvolatile,
+                                       &nonvol);
+                               ledger_get_balance(
+                                       task->ledger,
+                                       task_ledgers.purgeable_nonvolatile_compressed,
+                                       &nonvol_compressed);
+                               if (nonvol + nonvol_compressed == 0) {
+                                       /* nothing to report */
+                                       vm_map_unlock_read(map);
+                                       vm_map_deallocate(map);
+                                       return 0;
+                               }
+                               /* provide fake region for purgeable */
+                               pinfo->pri_offset = address;
+                               pinfo->pri_protection = VM_PROT_DEFAULT;
+                               pinfo->pri_max_protection = VM_PROT_DEFAULT;
+                               pinfo->pri_inheritance = VM_INHERIT_NONE;
+                               pinfo->pri_behavior = VM_BEHAVIOR_DEFAULT;
+                               pinfo->pri_user_wired_count = 0;
+                               pinfo->pri_user_tag = -1;
+                               pinfo->pri_pages_resident =
+                                       (uint32_t) (nonvol / PAGE_SIZE);
+                               pinfo->pri_pages_shared_now_private = 0;
+                               pinfo->pri_pages_swapped_out =
+                                       (uint32_t) (nonvol_compressed / PAGE_SIZE);
+                               pinfo->pri_pages_dirtied =
+                                       (uint32_t) (nonvol / PAGE_SIZE);
+                               pinfo->pri_ref_count = 1;
+                               pinfo->pri_shadow_depth = 0;
+                               pinfo->pri_share_mode = SM_PRIVATE;
+                               pinfo->pri_private_pages_resident =
+                                       (uint32_t) (nonvol / PAGE_SIZE);
+                               pinfo->pri_shared_pages_resident = 0;
+                               pinfo->pri_obj_id = INFO_MAKE_FAKE_OBJECT_ID(map, task_ledgers.purgeable_nonvolatile);
+                               pinfo->pri_address = address;
+                               pinfo->pri_size =
+                                       (uint64_t) (nonvol + nonvol_compressed);
+                               pinfo->pri_depth = 0;
+
+                               vm_map_unlock_read(map);
+                               vm_map_deallocate(map);
+                               return 1;
+                       }
                        vm_map_unlock_read(map);
-                       vm_map_deallocate(map); 
-                       return(0);
+                       vm_map_deallocate(map);
+                       return 0;
                }
            } else {
                entry = tmp_entry;
@@ -1020,7 +1082,7 @@ fill_procregioninfo(task_t task, uint64_t arg, struct proc_regioninfo_internal *
            extended.external_pager = 0;
            extended.shadow_depth = 0;
 
-           vm_map_region_walk(map, start, entry, VME_OFFSET(entry), entry->vme_end - start, &extended);
+           vm_map_region_walk(map, start, entry, VME_OFFSET(entry), entry->vme_end - start, &extended, TRUE, VM_REGION_EXTENDED_INFO_COUNT);
 
            if (extended.external_pager && extended.ref_count == 2 && extended.share_mode == SM_SHARED)
                    extended.share_mode = SM_PRIVATE;
index f68d9c5aa938595772b090c41003e4b98a51ec42..c8f3343f19ad7073b96e8a2980f9fbcabc933f67 100644 (file)
@@ -555,4 +555,19 @@ vm32__task_wire(
        return(KERN_SUCCESS);
 }
 
+kern_return_t
+vm32__map_exec_lockdown(
+       vm_map_t        map)
+{
+       if (map == VM_MAP_NULL)
+               return(KERN_INVALID_ARGUMENT);
+
+       vm_map_lock(map);
+       map->map_disallow_new_exec = TRUE;
+       vm_map_unlock(map);
+
+       return(KERN_SUCCESS);
+}
+
+
 #endif /* VM32_SUPPORT */
index 919dbe8b27886f19295ffd4177e6418ccafa5b5d..f474385b7d7da5f7b91905e1f339d8ae475ee692 100644 (file)
@@ -849,7 +849,7 @@ c_seg_need_delayed_compaction(c_segment_t c_seg, boolean_t c_list_lock_held)
        }
        assert(c_seg->c_state != C_IS_FILLING);
 
-       if (!c_seg->c_on_minorcompact_q && !(C_SEG_IS_ONDISK(c_seg))) {
+       if (!c_seg->c_on_minorcompact_q && !(C_SEG_IS_ON_DISK_OR_SOQ(c_seg))) {
                queue_enter(&c_minor_list_head, c_seg, c_segment_t, c_list);
                c_seg->c_on_minorcompact_q = 1;
                c_minor_count++;
@@ -953,6 +953,7 @@ c_seg_do_minor_compaction_and_unlock(c_segment_t c_seg, boolean_t clear_busy, bo
        int     c_seg_freed;
 
        assert(c_seg->c_busy);
+       assert(!C_SEG_IS_ON_DISK_OR_SOQ(c_seg));
 
        /*
         * check for the case that can occur when we are not swapping
@@ -2999,14 +3000,14 @@ c_current_seg_filled(c_segment_t c_seg, c_segment_t *current_chead)
 
        lck_mtx_lock_spin_always(c_list_lock);
 
+       c_seg->c_generation_id = c_generation_id++;
+       c_seg_switch_state(c_seg, new_state, FALSE);
+
 #if CONFIG_FREEZE
        if (c_seg->c_state == C_ON_SWAPOUT_Q)
                c_freezer_swapout_count++;
 #endif /* CONFIG_FREEZE */
 
-       c_seg->c_generation_id = c_generation_id++;
-       c_seg_switch_state(c_seg, new_state, FALSE);
-
        if (c_seg->c_state == C_ON_AGE_Q && C_SEG_UNUSED_BYTES(c_seg) >= PAGE_SIZE)
                c_seg_need_delayed_compaction(c_seg, TRUE);
 
@@ -3781,6 +3782,7 @@ bypass_busy_check:
                } else if (c_seg->c_on_minorcompact_q) {
 
                        assert(c_seg->c_state != C_ON_BAD_Q);
+                       assert(!C_SEG_IS_ON_DISK_OR_SOQ(c_seg));
 
                        if (C_SEG_SHOULD_MINORCOMPACT_NOW(c_seg)) {
                                c_seg_try_minor_compaction_and_unlock(c_seg);
index ad2f586fe1b439f1cf85c85b38342750ba396704..4b0883873b3293e2710f76d0ee5dc35209a5e025 100644 (file)
@@ -65,6 +65,7 @@
 
 #endif
 
+
 #if DEBUG || COMPRESSOR_INTEGRITY_CHECKS
 #define ENABLE_SWAP_CHECKS 1
 #define ENABLE_COMPRESSOR_CHECKS 1
@@ -219,6 +220,9 @@ extern      vm_offset_t     c_buffers;
 
 #define        C_SEG_ONDISK_IS_SPARSE(cseg)    ((cseg->c_bytes_used < cseg->c_bytes_unused) ? 1 : 0)
 #define C_SEG_IS_ONDISK(cseg)          ((cseg->c_state == C_ON_SWAPPEDOUT_Q || cseg->c_state == C_ON_SWAPPEDOUTSPARSE_Q))
+#define C_SEG_IS_ON_DISK_OR_SOQ(cseg)  ((cseg->c_state == C_ON_SWAPPEDOUT_Q || \
+                                         cseg->c_state == C_ON_SWAPPEDOUTSPARSE_Q || \
+                                         cseg->c_state == C_ON_SWAPOUT_Q))
 
 
 #define C_SEG_WAKEUP_DONE(cseg)                                \
index 3af35c8ec87d4ac6a20350a6fde0e9b6ad874634..9411412c62272518881d6d7de98476678a3ac6f8 100644 (file)
@@ -417,7 +417,7 @@ void vm_compressor_algorithm_init(void) {
 
        PE_parse_boot_argn("vm_compressor_codec", &new_codec, sizeof(new_codec));
        assertf(((new_codec == VM_COMPRESSOR_DEFAULT_CODEC) || (new_codec == CMODE_WK) ||
-               (new_codec == CMODE_LZ4) || (new_codec = CMODE_HYB)),
+               (new_codec == CMODE_LZ4) || (new_codec == CMODE_HYB)),
            "Invalid VM compression codec: %u", new_codec);
 
 #if defined(__arm__)||defined(__arm64__)
index 4a2eb0feabcf3b4813eaef61d46d15cc753e1aef..f4ec70ce5747307fd048635d1bcc9971d300644a 100644 (file)
@@ -1337,6 +1337,10 @@ retry:
        return KERN_FAILURE;
 
 done:  
+       assert(c_seg->c_busy_swapping);
+       assert(c_seg->c_busy);
+       assert(!c_seg->c_on_minorcompact_q);
+
        error = vm_swapfile_io(swf->swp_vp, file_offset, addr, (int) (size / PAGE_SIZE_64), SWAP_WRITE);
 
        lck_mtx_lock(&vm_swap_data_lock);
index 28aa9421869da2e4d9e55480d79e5360ae6f4f75..f6a8e5e5c1dd4ca5efe3f110b6c87a963acb3349 100644 (file)
@@ -220,20 +220,6 @@ static boolean_t   vm_map_fork_copy(
        vm_map_t        new_map,
        int             vm_map_copyin_flags);
 
-void           vm_map_region_top_walk(
-       vm_map_entry_t             entry,
-       vm_region_top_info_t       top);
-
-void           vm_map_region_walk(
-       vm_map_t                   map,
-       vm_map_offset_t            va,
-       vm_map_entry_t             entry,
-       vm_object_offset_t         offset,
-       vm_object_size_t           range,
-       vm_region_extended_info_t  extended,
-       boolean_t                  look_for_pages,
-       mach_msg_type_number_t count);
-
 static kern_return_t   vm_map_wire_nested(
        vm_map_t                   map,
        vm_map_offset_t            start,
@@ -1052,6 +1038,7 @@ vm_map_create(
        result->disable_vmentry_reuse = FALSE;
        result->map_disallow_data_exec = FALSE;
        result->is_nested_map = FALSE;
+       result->map_disallow_new_exec = FALSE;
        result->highest_entry_end = 0;
        result->first_free = vm_map_to_entry(result);
        result->hint = vm_map_to_entry(result);
@@ -2015,9 +2002,20 @@ vm_map_enter(
        kern_return_t           kr;
        boolean_t               clear_map_aligned = FALSE;
        vm_map_entry_t          hole_entry;
+       vm_map_size_t           chunk_size = 0;
 
        assertf(vmk_flags.__vmkf_unused == 0, "vmk_flags unused=0x%x\n", vmk_flags.__vmkf_unused);
 
+       if (flags & VM_FLAGS_4GB_CHUNK) {
+#if defined(__LP64__)
+               chunk_size = (4ULL * 1024 * 1024 * 1024); /* max. 4GB chunks for the new allocation */
+#else /* __LP64__ */
+               chunk_size = ANON_CHUNK_SIZE;
+#endif /* __LP64__ */
+       } else {
+               chunk_size = ANON_CHUNK_SIZE;
+       }
+
        if (superpage_size) {
                switch (superpage_size) {
                        /*
@@ -2055,6 +2053,16 @@ vm_map_enter(
        }
 #endif /* CONFIG_EMBEDDED */
 
+       /*
+        * If the task has requested executable lockdown,
+        * deny any new executable mapping.
+        */
+       if (map->map_disallow_new_exec == TRUE) {
+               if (cur_protection & VM_PROT_EXECUTE) {
+                       return KERN_PROTECTION_FAILURE;
+               }
+       }
+
        if (resilient_codesign || resilient_media) {
                if ((cur_protection & (VM_PROT_WRITE | VM_PROT_EXECUTE)) ||
                    (max_protection & (VM_PROT_WRITE | VM_PROT_EXECUTE))) {
@@ -2655,25 +2663,22 @@ StartAgain: ;
                tmp2_end = tmp2_start + step;
                /*
                 *      Create a new entry
-                *      LP64todo - for now, we can only allocate 4GB internal objects
-                *      because the default pager can't page bigger ones.  Remove this
-                *      when it can.
                 *
                 * XXX FBDP
                 * The reserved "page zero" in each process's address space can
-                * be arbitrarily large.  Splitting it into separate 4GB objects and
+                * be arbitrarily large.  Splitting it into separate objects and
                 * therefore different VM map entries serves no purpose and just
                 * slows down operations on the VM map, so let's not split the
-                * allocation into 4GB chunks if the max protection is NONE.  That
+                * allocation into chunks if the max protection is NONE.  That
                 * memory should never be accessible, so it will never get to the
                 * default pager.
                 */
                tmp_start = tmp2_start;
                if (object == VM_OBJECT_NULL &&
-                   size > (vm_map_size_t)ANON_CHUNK_SIZE &&
+                   size > chunk_size &&
                    max_protection != VM_PROT_NONE &&
                    superpage_size == 0)
-                       tmp_end = tmp_start + (vm_map_size_t)ANON_CHUNK_SIZE;
+                       tmp_end = tmp_start + chunk_size;
                else
                        tmp_end = tmp2_end;
                do {
@@ -2831,8 +2836,8 @@ StartAgain: ;
                        }
                } while (tmp_end != tmp2_end &&
                         (tmp_start = tmp_end) &&
-                        (tmp_end = (tmp2_end - tmp_end > (vm_map_size_t)ANON_CHUNK_SIZE) ?
-                         tmp_end + (vm_map_size_t)ANON_CHUNK_SIZE : tmp2_end));
+                        (tmp_end = (tmp2_end - tmp_end > chunk_size) ?
+                         tmp_end + chunk_size : tmp2_end));
        }
 
        new_mapping_established = TRUE;
@@ -3096,6 +3101,16 @@ vm_map_enter_fourk(
        }
 #endif /* CONFIG_EMBEDDED */
 
+       /*
+        * If the task has requested executable lockdown,
+        * deny any new executable mapping.
+        */
+       if (map->map_disallow_new_exec == TRUE) {
+               if (cur_protection & VM_PROT_EXECUTE) {
+                       return KERN_PROTECTION_FAILURE;
+               }
+       }
+
        if (is_submap) {
                return KERN_NOT_SUPPORTED;
        }
@@ -5494,6 +5509,20 @@ vm_map_protect(
                }
 #endif
 
+               /*
+                * If the task has requested executable lockdown,
+                * deny both:
+                * - adding executable protections OR
+                * - adding write protections to an existing executable mapping.
+                */
+               if (map->map_disallow_new_exec == TRUE) {
+                       if ((new_prot & VM_PROT_EXECUTE) ||
+                           ((current->protection & VM_PROT_EXECUTE) && (new_prot & VM_PROT_WRITE))) {
+                               vm_map_unlock(map);
+                               return(KERN_PROTECTION_FAILURE);
+                       }
+               }
+
                prev = current->vme_end;
                current = current->vme_next;
        }
@@ -7634,6 +7663,7 @@ vm_map_delete(
                                                     (entry->vme_end -
                                                      entry->vme_start));
                        entry->iokit_acct = FALSE;
+                       entry->use_pmap = FALSE;
                }
 
                /*
@@ -8388,6 +8418,8 @@ start_overwrite:
                                        vm_map_clip_start(
                                                dst_map, entry, sub_start);
                                        assert(!entry->use_pmap);
+                                       assert(!entry->iokit_acct);
+                                       entry->use_pmap = TRUE;
                                        entry->is_sub_map = FALSE;
                                        vm_map_deallocate(
                                                VME_SUBMAP(entry));
@@ -9460,6 +9492,13 @@ vm_map_copy_overwrite_aligned(
                                }
                        }
 
+                       if (entry->iokit_acct) {
+                               /* keep using iokit accounting */
+                               entry->use_pmap = FALSE;
+                       } else {
+                               /* use pmap accounting */
+                               entry->use_pmap = TRUE;
+                       }
                        entry->is_sub_map = FALSE;
                        VME_OBJECT_SET(entry, VME_OBJECT(copy_entry));
                        object = VME_OBJECT(entry);
@@ -10726,6 +10765,19 @@ vm_map_copyin_internal(
                if (new_entry->is_sub_map) {
                        /* clr address space specifics */
                        new_entry->use_pmap = FALSE;
+               } else {
+                       /*
+                        * We're dealing with a copy-on-write operation,
+                        * so the resulting mapping should not inherit the
+                        * original mapping's accounting settings.
+                        * "iokit_acct" should have been cleared in
+                        * vm_map_entry_copy().
+                        * "use_pmap" should be reset to its default (TRUE)
+                        * so that the new mapping gets accounted for in
+                        * the task's memory footprint.
+                        */
+                       assert(!new_entry->iokit_acct);
+                       new_entry->use_pmap = TRUE;
                }
 
                /*
@@ -10735,8 +10787,7 @@ vm_map_copyin_internal(
                if (src_destroy &&
                    (src_object == VM_OBJECT_NULL ||
                     (src_object->internal &&
-                     src_object->copy_strategy != MEMORY_OBJECT_COPY_DELAY &&
-                     !src_object->true_share &&
+                     src_object->copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC &&
                      !map_share))) {
                        /*
                         * If we are destroying the source, and the object
@@ -10844,7 +10895,6 @@ vm_map_copyin_internal(
                                &VME_OBJECT(new_entry));
                        VME_OFFSET_SET(new_entry, 0);
                        new_entry->needs_copy = FALSE;
-
                }
                else if (src_object->copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC &&
                         (entry_was_shared  || map_share)) {
@@ -10864,7 +10914,7 @@ vm_map_copyin_internal(
                        new_entry->needs_copy = TRUE;
                        assert(!new_entry->iokit_acct);
                        assert(new_object->purgable == VM_PURGABLE_DENY);
-                       new_entry->use_pmap = TRUE;
+                       assertf(new_entry->use_pmap, "src_map %p new_entry %p\n", src_map, new_entry);
                        result = KERN_SUCCESS;
 
                } else {
@@ -10912,6 +10962,8 @@ vm_map_copyin_internal(
                        }
                        vm_object_unlock(new_object);
                        new_object = VM_OBJECT_NULL;
+                       /* no pmap accounting for purgeable objects */
+                       new_entry->use_pmap = FALSE;
                }
 
                if (result != KERN_SUCCESS &&
@@ -10955,7 +11007,8 @@ vm_map_copyin_internal(
                        if (result != KERN_MEMORY_RESTART_COPY) {
                                vm_object_deallocate(VME_OBJECT(new_entry));
                                VME_OBJECT_SET(new_entry, VM_OBJECT_NULL);
-                               assert(!new_entry->iokit_acct);
+                               /* reset accounting state */
+                               new_entry->iokit_acct = FALSE;
                                new_entry->use_pmap = TRUE;
                        }
                        RETURN(KERN_INVALID_ADDRESS);
@@ -11445,6 +11498,7 @@ vm_map_fork_share(
                VME_OFFSET_SET(old_entry, 0);
                VME_OBJECT_SET(old_entry, object);
                old_entry->use_pmap = TRUE;
+//             assert(!old_entry->needs_copy);
        } else if (object->copy_strategy !=
                   MEMORY_OBJECT_COPY_SYMMETRIC) {
 
@@ -11619,6 +11673,15 @@ vm_map_fork_share(
        old_entry->is_shared = TRUE;
        new_entry->is_shared = TRUE;
 
+       /*
+        * We're dealing with a shared mapping, so the resulting mapping
+        * should inherit some of the original mapping's accounting settings.
+        * "iokit_acct" should have been cleared in vm_map_entry_copy().
+        * "use_pmap" should stay the same as before (if it hasn't been reset
+        * to TRUE when we cleared "iokit_acct").
+        */
+       assert(!new_entry->iokit_acct);
+
        /*
         *      If old entry's inheritence is VM_INHERIT_NONE,
         *      the new entry is for corpse fork, remove the
@@ -11832,6 +11895,19 @@ vm_map_fork(
                        if (new_entry->is_sub_map) {
                                /* clear address space specifics */
                                new_entry->use_pmap = FALSE;
+                       } else {
+                               /*
+                                * We're dealing with a copy-on-write operation,
+                                * so the resulting mapping should not inherit
+                                * the original mapping's accounting settings.
+                                * "iokit_acct" should have been cleared in
+                                * vm_map_entry_copy().
+                                * "use_pmap" should be reset to its default
+                                * (TRUE) so that the new mapping gets
+                                * accounted for in the task's memory footprint.
+                                */
+                               assert(!new_entry->iokit_acct);
+                               new_entry->use_pmap = TRUE;
                        }
 
                        if (! vm_object_copy_quickly(
@@ -12186,6 +12262,8 @@ submap_recurse:
                                                 submap_entry->vme_start));
                                VME_OBJECT_SET(submap_entry, sub_object);
                                VME_OFFSET_SET(submap_entry, 0);
+                               assert(!submap_entry->is_sub_map);
+                               assert(submap_entry->use_pmap);
                        }
                        local_start =  local_vaddr -
                                (cow_parent_vaddr - old_start);
@@ -12477,6 +12555,7 @@ submap_recurse:
                                       (vm_map_size_t)(entry->vme_end -
                                                       entry->vme_start)));
                VME_OFFSET_SET(entry, 0);
+               assert(entry->use_pmap);
                vm_map_lock_write_to_read(map);
        }
 
@@ -12565,10 +12644,6 @@ vm_map_verify(
  *
  */
 
-#if DEVELOPMENT || DEBUG
-int vm_region_footprint = 0;
-#endif /* DEVELOPMENT || DEBUG */
-
 kern_return_t
 vm_map_region_recurse_64(
        vm_map_t                 map,
@@ -12625,6 +12700,7 @@ vm_map_region_recurse_64(
 
        boolean_t                       look_for_pages;
        vm_region_submap_short_info_64_t short_info;
+       boolean_t                       do_region_footprint;
 
        if (map == VM_MAP_NULL) {
                /* no address space to work on */
@@ -12640,6 +12716,7 @@ vm_map_region_recurse_64(
                return KERN_INVALID_ARGUMENT;
        }
 
+       do_region_footprint = task_self_region_footprint();
        original_count = *count;
 
        if (original_count < VM_REGION_SUBMAP_INFO_V0_COUNT_64) {
@@ -12829,14 +12906,17 @@ recurse_again:
                curr_entry = NULL;
        }
 
+// LP64todo: all the current tools are 32bit, obviously never worked for 64b
+// so probably should be a real 32b ID vs. ptr.
+// Current users just check for equality
+
        if (curr_entry == NULL) {
                /* no VM region contains the address... */
-#if DEVELOPMENT || DEBUG
-               if (vm_region_footprint && /* we want footprint numbers */
-                   look_for_pages && /* & we want page counts */
+
+               if (do_region_footprint && /* we want footprint numbers */
                    next_entry == NULL && /* & there are no more regions */
                    /* & we haven't already provided our fake region: */
-                   user_address == vm_map_last_entry(map)->vme_end) {
+                   user_address <= vm_map_last_entry(map)->vme_end) {
                        ledger_amount_t nonvol, nonvol_compressed;
                        /*
                         * Add a fake memory region to account for
@@ -12855,33 +12935,50 @@ recurse_again:
                                &nonvol_compressed);
                        if (nonvol + nonvol_compressed == 0) {
                                /* no purgeable memory usage to report */
-                               return KERN_FAILURE;
+                               return KERN_INVALID_ADDRESS;
                        }
                        /* fake region to show nonvolatile footprint */
-                       submap_info->protection = VM_PROT_DEFAULT;
-                       submap_info->max_protection = VM_PROT_DEFAULT;
-                       submap_info->inheritance = VM_INHERIT_DEFAULT;
-                       submap_info->offset = 0;
-                       submap_info->user_tag = 0;
-                       submap_info->pages_resident = (unsigned int) (nonvol / PAGE_SIZE);
-                       submap_info->pages_shared_now_private = 0;
-                       submap_info->pages_swapped_out = (unsigned int) (nonvol_compressed / PAGE_SIZE);
-                       submap_info->pages_dirtied = submap_info->pages_resident;
-                       submap_info->ref_count = 1;
-                       submap_info->shadow_depth = 0;
-                       submap_info->external_pager = 0;
-                       submap_info->share_mode = SM_PRIVATE;
-                       submap_info->is_submap = 0;
-                       submap_info->behavior = VM_BEHAVIOR_DEFAULT;
-                       submap_info->object_id = 0x11111111;
-                       submap_info->user_wired_count = 0;
-                       submap_info->pages_reusable = 0;
+                       if (look_for_pages) {
+                               submap_info->protection = VM_PROT_DEFAULT;
+                               submap_info->max_protection = VM_PROT_DEFAULT;
+                               submap_info->inheritance = VM_INHERIT_DEFAULT;
+                               submap_info->offset = 0;
+                               submap_info->user_tag = -1;
+                               submap_info->pages_resident = (unsigned int) (nonvol / PAGE_SIZE);
+                               submap_info->pages_shared_now_private = 0;
+                               submap_info->pages_swapped_out = (unsigned int) (nonvol_compressed / PAGE_SIZE);
+                               submap_info->pages_dirtied = submap_info->pages_resident;
+                               submap_info->ref_count = 1;
+                               submap_info->shadow_depth = 0;
+                               submap_info->external_pager = 0;
+                               submap_info->share_mode = SM_PRIVATE;
+                               submap_info->is_submap = 0;
+                               submap_info->behavior = VM_BEHAVIOR_DEFAULT;
+                               submap_info->object_id = INFO_MAKE_FAKE_OBJECT_ID(map, task_ledgers.purgeable_nonvolatile);
+                               submap_info->user_wired_count = 0;
+                               submap_info->pages_reusable = 0;
+                       } else {
+                               short_info->user_tag = -1;
+                               short_info->offset = 0;
+                               short_info->protection = VM_PROT_DEFAULT;
+                               short_info->inheritance = VM_INHERIT_DEFAULT;
+                               short_info->max_protection = VM_PROT_DEFAULT;
+                               short_info->behavior = VM_BEHAVIOR_DEFAULT;
+                               short_info->user_wired_count = 0;
+                               short_info->is_submap = 0;
+                               short_info->object_id = INFO_MAKE_FAKE_OBJECT_ID(map, task_ledgers.purgeable_nonvolatile);
+                               short_info->external_pager = 0;
+                               short_info->shadow_depth = 0;
+                               short_info->share_mode = SM_PRIVATE;
+                               short_info->ref_count = 1;
+                       }
                        *nesting_depth = 0;
                        *size = (vm_map_size_t) (nonvol + nonvol_compressed);
-                       *address = user_address;
+//                     *address = user_address;
+                       *address = vm_map_last_entry(map)->vme_end;
                        return KERN_SUCCESS;
                }
-#endif /* DEVELOPMENT || DEBUG */
+
                if (next_entry == NULL) {
                        /* ... and no VM region follows it either */
                        return KERN_INVALID_ADDRESS;
@@ -13350,6 +13447,9 @@ vm_map_region_walk(
        int               ref_count;
        struct vm_object        *shadow_object;
        int                     shadow_depth;
+       boolean_t         do_region_footprint;
+
+       do_region_footprint = task_self_region_footprint();
 
        if ((VME_OBJECT(entry) == 0) ||
            (entry->is_sub_map) ||
@@ -13381,53 +13481,60 @@ vm_map_region_walk(
                for (last_offset = offset + range;
                     offset < last_offset;
                     offset += PAGE_SIZE_64, va += PAGE_SIZE) {
-#if DEVELOPMENT || DEBUG
-                       if (vm_region_footprint) {
+
+                       if (do_region_footprint) {
+                               int disp;
+
+                               disp = 0;
+                               pmap_query_page_info(map->pmap, va, &disp);
+                               if (disp & PMAP_QUERY_PAGE_PRESENT) {
+                                       extended->pages_resident++;
+                                       if (disp & PMAP_QUERY_PAGE_REUSABLE) {
+                                               extended->pages_reusable++;
+                                       } else if (!(disp & PMAP_QUERY_PAGE_INTERNAL) ||
+                                                  (disp & PMAP_QUERY_PAGE_ALTACCT)) {
+                                               /* alternate accounting */
+                                       } else {
+                                               extended->pages_dirtied++;
+                                       }
+                               } else if (disp & PMAP_QUERY_PAGE_COMPRESSED) {
+                                       if (disp & PMAP_QUERY_PAGE_COMPRESSED_ALTACCT) {
+                                               /* alternate accounting */
+                                       } else {
+                                               extended->pages_swapped_out++;
+                                       }
+                               }
+                               /* deal with alternate accounting */
                                if (obj->purgable != VM_PURGABLE_DENY) {
-                                       /* alternate accounting */
+                                       /*
+                                        * Pages from purgeable objects
+                                        * will be reported as dirty 
+                                        * appropriately in an extra
+                                        * fake memory region at the end of
+                                        * the address space.
+                                        */
                                } else if (entry->iokit_acct) {
-                                       /* alternate accounting */
-                                       extended->pages_resident++;
+                                       /*
+                                        * IOKit mappings are considered
+                                        * as fully dirty for footprint's
+                                        * sake.
+                                        */
                                        extended->pages_dirtied++;
-                               } else {
-                                       int disp;
-
-                                       disp = 0;
-                                       pmap_query_page_info(map->pmap, va, &disp);
-                                       if (disp & PMAP_QUERY_PAGE_PRESENT) {
-                                               extended->pages_resident++;
-                                               if (disp & PMAP_QUERY_PAGE_REUSABLE) {
-                                                       extended->pages_reusable++;
-                                               } else if (!(disp & PMAP_QUERY_PAGE_INTERNAL) ||
-                                                          (disp & PMAP_QUERY_PAGE_ALTACCT)) {
-                                                       /* alternate accounting */
-                                               } else {
-                                                       extended->pages_dirtied++;
-                                               }
-                                       } else if (disp & PMAP_QUERY_PAGE_COMPRESSED) {
-                                               if (disp & PMAP_QUERY_PAGE_COMPRESSED_ALTACCT) {
-                                                       /* alternate accounting */
-                                               } else {
-                                                       extended->pages_swapped_out++;
-                                               }
-                                       }
                                }
                                continue;
                        }
-#endif /* DEVELOPMENT || DEBUG */
+
                        vm_map_region_look_for_page(map, va, obj,
                                                    offset, ref_count,
                                                    0, extended, count);
                }
-#if DEVELOPMENT || DEBUG
-               if (vm_region_footprint) {
+
+               if (do_region_footprint) {
                        goto collect_object_info;
                }
-#endif /* DEVELOPMENT || DEBUG */
+
        } else {
-#if DEVELOPMENT || DEBUG
        collect_object_info:
-#endif /* DEVELOPMENT || DEBUG */
                shadow_object = obj->shadow;
                shadow_depth = 0;
 
@@ -14681,6 +14788,11 @@ vm_map_entry_insert(
 
        assert(insp_entry != (vm_map_entry_t)0);
 
+#if DEVELOPMENT || DEBUG
+       vm_object_offset_t      end_offset = 0;
+       assertf(!os_add_overflow(end - start, offset, &end_offset), "size 0x%llx, offset 0x%llx caused overflow", (uint64_t)(end - start), offset);
+#endif /* DEVELOPMENT || DEBUG */
+
        new_entry = vm_map_entry_create(map, !map->hdr.entries_pageable);
 
        if (VM_MAP_PAGE_SHIFT(map) != PAGE_SHIFT) {
@@ -14804,6 +14916,8 @@ vm_map_remap_extract(
        vm_map_version_t        version;
        boolean_t               src_needs_copy;
        boolean_t               new_entry_needs_copy;
+       vm_map_entry_t          saved_src_entry;
+       boolean_t               src_entry_was_wired;
 
        assert(map != VM_MAP_NULL);
        assert(size != 0);
@@ -14881,19 +14995,36 @@ vm_map_remap_extract(
                                 * Purgeable objects have their own accounting:
                                 * no pmap accounting for them.
                                 */
-                               assert(!src_entry->use_pmap);
+                               assertf(!src_entry->use_pmap,
+                                       "map=%p src_entry=%p [0x%llx:0x%llx] 0x%x/0x%x %d",
+                                       map,
+                                       src_entry,
+                                       (uint64_t)src_entry->vme_start,
+                                       (uint64_t)src_entry->vme_end,
+                                       src_entry->protection,
+                                       src_entry->max_protection,
+                                       VME_ALIAS(src_entry));
                        } else {
                                /*
                                 * Not IOKit or purgeable:
                                 * must be accounted by pmap stats.
                                 */
-                               assert(src_entry->use_pmap);
+                               assertf(src_entry->use_pmap,
+                                       "map=%p src_entry=%p [0x%llx:0x%llx] 0x%x/0x%x %d",
+                                       map,
+                                       src_entry,
+                                       (uint64_t)src_entry->vme_start,
+                                       (uint64_t)src_entry->vme_end,
+                                       src_entry->protection,
+                                       src_entry->max_protection,
+                                       VME_ALIAS(src_entry));
                        }
 
                        if (object == VM_OBJECT_NULL) {
                                object = vm_object_allocate(entry_size);
                                VME_OFFSET_SET(src_entry, 0);
                                VME_OBJECT_SET(src_entry, object);
+                               assert(src_entry->use_pmap);
                        } else if (object->copy_strategy !=
                                   MEMORY_OBJECT_COPY_SYMMETRIC) {
                                /*
@@ -14908,6 +15039,7 @@ vm_map_remap_extract(
                                    object->vo_size > entry_size)) {
 
                                VME_OBJECT_SHADOW(src_entry, entry_size);
+                               assert(src_entry->use_pmap);
 
                                if (!src_entry->needs_copy &&
                                    (src_entry->protection & VM_PROT_WRITE)) {
@@ -14963,7 +15095,19 @@ vm_map_remap_extract(
                if (new_entry->is_sub_map) {
                        /* clr address space specifics */
                        new_entry->use_pmap = FALSE;
+               } else if (copy) {
+                       /*
+                        * We're dealing with a copy-on-write operation,
+                        * so the resulting mapping should not inherit the
+                        * original mapping's accounting settings.
+                        * "use_pmap" should be reset to its default (TRUE)
+                        * so that the new mapping gets accounted for in
+                        * the task's memory footprint.
+                        */
+                       new_entry->use_pmap = TRUE;
                }
+               /* "iokit_acct" was cleared in vm_map_entry_copy() */
+               assert(!new_entry->iokit_acct);
 
                new_entry->map_aligned = FALSE;
 
@@ -15019,6 +15163,7 @@ vm_map_remap_extract(
 
                        new_entry->needs_copy = new_entry_needs_copy;
                        new_entry->is_shared = FALSE;
+                       assertf(new_entry->use_pmap, "map %p new_entry %p\n", map, new_entry);
 
                        /*
                         * Handle copy_on_write semantics.
@@ -15056,6 +15201,11 @@ vm_map_remap_extract(
 
                } else {
                        new_entry->is_shared = FALSE;
+                       assertf(new_entry->use_pmap, "map %p new_entry %p\n", map, new_entry);
+
+                       src_entry_was_wired = (src_entry->wired_count > 0);
+                       saved_src_entry = src_entry;
+                       src_entry = VM_MAP_ENTRY_NULL;
 
                        /*
                         * The map can be safely unlocked since we
@@ -15070,7 +15220,7 @@ vm_map_remap_extract(
                        /*
                         * Perform the copy.
                         */
-                       if (src_entry->wired_count > 0) {
+                       if (src_entry_was_wired > 0) {
                                vm_object_lock(object);
                                result = vm_object_copy_slowly(
                                        object,
@@ -15126,12 +15276,16 @@ vm_map_remap_extract(
                                 * Retry the lookup and verify that the
                                 * same object/offset are still present.
                                 */
+                               saved_src_entry = VM_MAP_ENTRY_NULL;
                                vm_object_deallocate(VME_OBJECT(new_entry));
                                _vm_map_entry_dispose(map_header, new_entry);
                                if (result == KERN_MEMORY_RESTART_COPY)
                                        result = KERN_SUCCESS;
                                continue;
                        }
+                       /* map hasn't changed: src_entry is still valid */
+                       src_entry = saved_src_entry;
+                       saved_src_entry = VM_MAP_ENTRY_NULL;
 
                        if (result == KERN_MEMORY_RESTART_COPY) {
                                vm_object_reference(object);
@@ -15961,6 +16115,7 @@ vm_map_page_range_info_internal(
        vm_page_info_basic_t    basic_info = 0;
        vm_map_offset_t         offset_in_page = 0, offset_in_object = 0, curr_offset_in_object = 0;
        vm_map_offset_t         start = 0, end = 0, curr_s_offset = 0, curr_e_offset = 0;
+       boolean_t               do_region_footprint;
 
        switch (flavor) {
        case VM_PAGE_INFO_BASIC:
@@ -15978,6 +16133,7 @@ vm_map_page_range_info_internal(
                return KERN_INVALID_ARGUMENT;
        }
 
+       do_region_footprint = task_self_region_footprint();
        disposition = 0;
        ref_count = 0;
        depth = 0;
@@ -16001,6 +16157,58 @@ vm_map_page_range_info_internal(
                ref_count = 0;
                depth = 0;
 
+               if (do_region_footprint &&
+                   curr_s_offset >= vm_map_last_entry(map)->vme_end) {
+                       ledger_amount_t nonvol_compressed;
+
+                       /*
+                        * Request for "footprint" info about a page beyond
+                        * the end of address space: this must be for
+                        * the fake region vm_map_region_recurse_64()
+                        * reported to account for non-volatile purgeable
+                        * memory owned by this task.
+                        */
+                       disposition = 0;
+                       nonvol_compressed = 0;
+                       ledger_get_balance(
+                               map->pmap->ledger,
+                               task_ledgers.purgeable_nonvolatile_compressed,
+                               &nonvol_compressed);
+                       if (curr_s_offset - vm_map_last_entry(map)->vme_end <=
+                           (unsigned) nonvol_compressed) {
+                               /*
+                                * We haven't reported all the "non-volatile
+                                * compressed" pages yet, so report this fake
+                                * page as "compressed".
+                                */
+                               disposition |= VM_PAGE_QUERY_PAGE_PAGED_OUT;
+                       } else {
+                               /*
+                                * We've reported all the non-volatile
+                                * compressed page but not all the non-volatile
+                                * pages , so report this fake page as
+                                * "resident dirty".
+                                */
+                               disposition |= VM_PAGE_QUERY_PAGE_PRESENT;
+                               disposition |= VM_PAGE_QUERY_PAGE_DIRTY;
+                               disposition |= VM_PAGE_QUERY_PAGE_REF;
+                       }
+                       switch (flavor) {
+                       case VM_PAGE_INFO_BASIC:
+                               basic_info = (vm_page_info_basic_t) (((uintptr_t) info) + (info_idx * sizeof(struct vm_page_info_basic)));
+                               basic_info->disposition = disposition;
+                               basic_info->ref_count = 1;
+                               basic_info->object_id = INFO_MAKE_FAKE_OBJECT_ID(map, task_ledgers.purgeable_nonvolatile);
+                               basic_info->offset = 0;
+                               basic_info->depth = 0;
+
+                               info_idx++;
+                               break;
+                       }
+                       curr_s_offset += PAGE_SIZE;
+                       continue;
+               }
+
                /*
                 * First, find the map entry covering "curr_s_offset", going down
                 * submaps if necessary.
@@ -16129,6 +16337,58 @@ vm_map_page_range_info_internal(
                        continue;
                }
 
+               if (do_region_footprint) {
+                       int pmap_disp;
+
+                       disposition = 0;
+                       pmap_disp = 0;
+                       pmap_query_page_info(map->pmap, curr_s_offset, &pmap_disp);
+                       if (map_entry->iokit_acct &&
+                           object->internal &&
+                           object->purgable == VM_PURGABLE_DENY) {
+                               /*
+                                * Non-purgeable IOKit memory: phys_footprint
+                                * includes the entire virtual mapping.
+                                */
+                               assertf(!map_entry->use_pmap, "offset 0x%llx map_entry %p", (uint64_t) curr_s_offset, map_entry);
+                               disposition |= VM_PAGE_QUERY_PAGE_PRESENT;
+                               disposition |= VM_PAGE_QUERY_PAGE_DIRTY;
+                       } else if (pmap_disp & (PMAP_QUERY_PAGE_ALTACCT |
+                                               PMAP_QUERY_PAGE_COMPRESSED_ALTACCT)) {
+                               /* alternate accounting */
+                               assertf(!map_entry->use_pmap, "offset 0x%llx map_entry %p", (uint64_t) curr_s_offset, map_entry);
+                               pmap_disp = 0;
+                       } else {
+                               if (pmap_disp & PMAP_QUERY_PAGE_PRESENT) {
+                                       assertf(map_entry->use_pmap, "offset 0x%llx map_entry %p", (uint64_t) curr_s_offset, map_entry);
+                                       disposition |= VM_PAGE_QUERY_PAGE_PRESENT;
+                                       disposition |= VM_PAGE_QUERY_PAGE_REF;
+                                       if (pmap_disp & PMAP_QUERY_PAGE_INTERNAL) {
+                                               disposition |= VM_PAGE_QUERY_PAGE_DIRTY;
+                                       } else {
+                                               disposition |= VM_PAGE_QUERY_PAGE_EXTERNAL;
+                                       }
+                               } else if (pmap_disp & PMAP_QUERY_PAGE_COMPRESSED) {
+                                       assertf(map_entry->use_pmap, "offset 0x%llx map_entry %p", (uint64_t) curr_s_offset, map_entry);
+                                       disposition |= VM_PAGE_QUERY_PAGE_PAGED_OUT;
+                               }
+                       }
+                       switch (flavor) {
+                       case VM_PAGE_INFO_BASIC:
+                               basic_info = (vm_page_info_basic_t) (((uintptr_t) info) + (info_idx * sizeof(struct vm_page_info_basic)));
+                               basic_info->disposition = disposition;
+                               basic_info->ref_count = 1;
+                               basic_info->object_id = INFO_MAKE_FAKE_OBJECT_ID(map, task_ledgers.purgeable_nonvolatile);
+                               basic_info->offset = 0;
+                               basic_info->depth = 0;
+
+                               info_idx++;
+                               break;
+                       }
+                       curr_s_offset += PAGE_SIZE;
+                       continue;
+               }
+
                vm_object_reference(object);
                /*
                 * Shared mode -- so we can allow other readers
index f8e1aa62398d9beb04393b5c1b950ce6a5ec0324..23592b8e4d01130c82b18f0873a3b3e45dfe31dd 100644 (file)
@@ -238,6 +238,7 @@ struct vm_map_links {
        vm_object_shadow(&__object, &__offset, (length));       \
        if (__object != VME_OBJECT((entry))) {                  \
                VME_OBJECT_SET((entry), __object);              \
+               (entry)->use_pmap = TRUE;                       \
        }                                                       \
        if (__offset != VME_OFFSET((entry))) {                  \
                VME_OFFSET_SET((entry), __offset);              \
@@ -253,6 +254,35 @@ struct vm_map_links {
        (entry)->vme_offset = __offset | ((alias) & VME_ALIAS_MASK);    \
        MACRO_END
 
+/*
+ * FOOTPRINT ACCOUNTING:
+ * The "memory footprint" is better described in the pmap layer.
+ *
+ * At the VM level, these 2 vm_map_entry_t fields are relevant:
+ * iokit_mapped:
+ *     For an "iokit_mapped" entry, we add the size of the entry to the
+ *     footprint when the entry is entered into the map and we subtract that
+ *     size when the entry is removed.  No other accounting should take place.
+ *     "use_pmap" should be FALSE but is not taken into account.
+ * use_pmap: (only when is_sub_map is FALSE)
+ *     This indicates if we should ask the pmap layer to account for pages
+ *     in this mapping.  If FALSE, we expect that another form of accounting
+ *     is being used (e.g. "iokit_mapped" or the explicit accounting of
+ *     non-volatile purgable memory).
+ *
+ * So the logic is mostly:
+ * if entry->is_sub_map == TRUE
+ *     anything in a submap does not count for the footprint
+ * else if entry->iokit_mapped == TRUE
+ *     footprint includes the entire virtual size of this entry
+ * else if entry->use_pmap == FALSE
+ *     tell pmap NOT to account for pages being pmap_enter()'d from this
+ *     mapping (i.e. use "alternate accounting")
+ * else
+ *     pmap will account for pages being pmap_enter()'d from this mapping
+ *     as it sees fit (only if anonymous, etc...)
+ */
+
 struct vm_map_entry {
        struct vm_map_links     links;          /* links to other entries */
 #define vme_prev               links.prev
@@ -431,7 +461,8 @@ struct _vm_map {
        /* boolean_t */         map_disallow_data_exec:1, /* Disallow execution from data pages on exec-permissive architectures */
        /* boolean_t */         holelistenabled:1,
        /* boolean_t */         is_nested_map:1,
-       /* reserved */          pad:23;
+       /* boolean_t */         map_disallow_new_exec:1, /* Disallow new executable code */
+       /* reserved */          pad:22;
        unsigned int            timestamp;      /* Version number */
        unsigned int            color_rr;       /* next color (not protected by a lock) */
 
@@ -1018,6 +1049,19 @@ extern kern_return_t vm_map_set_cache_attr(
 
 extern int override_nx(vm_map_t map, uint32_t user_tag);
 
+extern void vm_map_region_top_walk(
+        vm_map_entry_t entry,
+       vm_region_top_info_t top);
+extern void vm_map_region_walk(
+       vm_map_t map,
+       vm_map_offset_t va,
+       vm_map_entry_t entry,
+       vm_object_offset_t offset,
+       vm_object_size_t range,
+       vm_region_extended_info_t extended,
+       boolean_t look_for_pages,
+       mach_msg_type_number_t count);
+
 #endif /* MACH_KERNEL_PRIVATE */
 
 __BEGIN_DECLS
@@ -1502,6 +1546,14 @@ extern kern_return_t vm_map_freeze(
 
 __END_DECLS
 
+/*
+ * In some cases, we don't have a real VM object but still want to return a
+ * unique ID (to avoid a memory region looking like shared memory), so build
+ * a fake pointer based on the map's ledger and the index of the ledger being
+ * reported.
+ */
+#define INFO_MAKE_FAKE_OBJECT_ID(map,ledger_id)        ((uint32_t)(uintptr_t)VM_KERNEL_ADDRPERM((int*)((map)->pmap->ledger)+(ledger_id)))
+
 #endif /* KERNEL_PRIVATE */
  
 #endif /* _VM_VM_MAP_H_ */
index a7820e3b0e330cbaae5d163378389edbd1b1a501..821929f88bffb6d9b25eac90d528d52de04a2aa2 100644 (file)
@@ -542,6 +542,8 @@ vm_object_bootstrap(void)
 
        vm_object_template.objq.next = NULL;
        vm_object_template.objq.prev = NULL;
+       vm_object_template.task_objq.next = NULL;
+       vm_object_template.task_objq.prev = NULL;
 
        vm_object_template.purgeable_queue_type = PURGEABLE_Q_TYPE_MAX;
        vm_object_template.purgeable_queue_group = 0;
@@ -1008,11 +1010,10 @@ vm_object_cache_remove_locked(
        vm_object_t     object)
 {
        assert(object->purgable == VM_PURGABLE_DENY);
-       assert(object->wired_page_count == 0);
 
-       queue_remove(&vm_object_cached_list, object, vm_object_t, objq);
-       object->objq.next = NULL;
-       object->objq.prev = NULL;
+       queue_remove(&vm_object_cached_list, object, vm_object_t, cached_list);
+       object->cached_list.next = NULL;
+       object->cached_list.prev = NULL;
 
        vm_object_cached_count--;
 }
@@ -1023,7 +1024,8 @@ vm_object_cache_remove(
 {
        vm_object_cache_lock_spin();
 
-       if (object->objq.next || object->objq.prev)
+       if (object->cached_list.next &&
+           object->cached_list.prev)
                vm_object_cache_remove_locked(object);
 
        vm_object_cache_unlock();
@@ -1037,7 +1039,6 @@ vm_object_cache_add(
        clock_nsec_t nsec;
 
        assert(object->purgable == VM_PURGABLE_DENY);
-       assert(object->wired_page_count == 0);
 
        if (object->resident_page_count == 0)
                return;
@@ -1045,8 +1046,9 @@ vm_object_cache_add(
 
        vm_object_cache_lock_spin();
 
-       if (object->objq.next == NULL && object->objq.prev == NULL) {
-               queue_enter(&vm_object_cached_list, object, vm_object_t, objq);
+       if (object->cached_list.next == NULL &&
+           object->cached_list.prev == NULL) {
+               queue_enter(&vm_object_cached_list, object, vm_object_t, cached_list);
                object->vo_cache_ts = sec + EVICT_AGE;
                object->vo_cache_pages_to_scan = object->resident_page_count;
 
@@ -1110,7 +1112,7 @@ vm_object_cache_evict(
                while (!queue_end(&vm_object_cached_list, (queue_entry_t)next_obj) && object_cnt++ < max_objects_to_examine) {
 
                        object = next_obj;
-                       next_obj = (vm_object_t)queue_next(&next_obj->objq);
+                       next_obj = (vm_object_t)queue_next(&next_obj->cached_list);
 
                        assert(object->purgable == VM_PURGABLE_DENY);
                        assert(object->wired_page_count == 0);
@@ -1351,7 +1353,9 @@ vm_object_terminate(
        object->terminating = TRUE;
        object->alive = FALSE;
 
-       if ( !object->internal && (object->objq.next || object->objq.prev))
+       if (!object->internal &&
+           object->cached_list.next &&
+           object->cached_list.prev)
                vm_object_cache_remove(object);
 
        /*
@@ -1452,7 +1456,8 @@ vm_object_reap(
            object->purgable != VM_PURGABLE_DENY) {
                vm_purgeable_accounting(object,
                                        object->purgable,
-                                       TRUE); /* disown */
+                                       TRUE, /* disown */
+                                       FALSE); /* task_objq locked? */
        }
 
        pager = object->pager;
@@ -1533,8 +1538,17 @@ vm_object_reap(
                        panic("object %p in unexpected purgeable state 0x%x\n",
                              object, object->purgable);
                }
-               assert(object->objq.next == NULL);
-               assert(object->objq.prev == NULL);
+               if (object->transposed &&
+                   object->cached_list.next != NULL &&
+                   object->cached_list.prev == NULL) {
+                       /*
+                        * object->cached_list.next "points" to the
+                        * object that was transposed with this object.
+                        */
+               } else {
+                       assert(object->cached_list.next == NULL);
+               }
+               assert(object->cached_list.prev == NULL);
        }
     
        if (object->pageout) {
@@ -5466,17 +5480,17 @@ vm_object_lock_request(
  * On entry the object must be locked and it must be
  * purgeable with no delayed copies pending.
  */
-void
+uint64_t
 vm_object_purge(vm_object_t object, int flags)
 {
-       unsigned int    object_page_count = 0;
-       unsigned int    pgcount = 0;
+       unsigned int    object_page_count = 0, pgcount = 0;
+       uint64_t        total_purged_pgcount = 0;
        boolean_t       skipped_object = FALSE;
 
         vm_object_lock_assert_exclusive(object);
 
        if (object->purgable == VM_PURGABLE_DENY)
-               return;
+               return 0;
 
        assert(object->copy == VM_OBJECT_NULL);
        assert(object->copy_strategy == MEMORY_OBJECT_COPY_NONE);
@@ -5522,6 +5536,12 @@ vm_object_purge(vm_object_t object, int flags)
 
        vm_object_reap_pages(object, REAP_PURGEABLE);
 
+       if (object->resident_page_count >= object_page_count) {
+               total_purged_pgcount = 0;
+       } else {
+               total_purged_pgcount = object_page_count - object->resident_page_count;
+       }
+
        if (object->pager != NULL) {
 
                assert(VM_CONFIG_COMPRESSOR_IS_PRESENT);
@@ -5575,13 +5595,16 @@ vm_object_purge(vm_object_t object, int flags)
 
        vm_object_lock_assert_exclusive(object);
 
+       total_purged_pgcount += pgcount;
+
        KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (MACHDBG_CODE(DBG_MACH_VM, OBJECT_PURGE_ONE)),
                              VM_KERNEL_UNSLIDE_OR_PERM(object), /* purged object */
                              object_page_count,
-                             pgcount,
+                             total_purged_pgcount,
                              skipped_object,
                              0);
 
+       return total_purged_pgcount;
 }
                                
 
@@ -5785,7 +5808,8 @@ vm_object_purgable_control(
                         * non-volatile ledgers.
                         */
                        vm_purgeable_accounting(object, VM_PURGABLE_VOLATILE,
-                                               FALSE);
+                                               FALSE, /* disown */
+                                               FALSE); /* task_objq locked? */
                }
 
                break;
@@ -5913,8 +5937,10 @@ vm_object_purgable_control(
                };
                vm_purgeable_object_add(object, queue, (*state&VM_VOLATILE_GROUP_MASK)>>VM_VOLATILE_GROUP_SHIFT );
                if (old_state == VM_PURGABLE_NONVOLATILE) {
-                       vm_purgeable_accounting(object, VM_PURGABLE_NONVOLATILE,
-                                               FALSE);
+                       vm_purgeable_accounting(object,
+                                               VM_PURGABLE_NONVOLATILE,
+                                               FALSE, /* disown */
+                                               FALSE); /* task_objq locked? */
                }
 
                assert(queue->debug_count_objects>=0);
@@ -5963,8 +5989,10 @@ vm_object_purgable_control(
                         * "non-volatile" and now need to be accounted as
                         * "volatile".
                         */
-                       vm_purgeable_accounting(object, VM_PURGABLE_NONVOLATILE,
-                                               FALSE);
+                       vm_purgeable_accounting(object,
+                                               VM_PURGABLE_NONVOLATILE,
+                                               FALSE, /* disown */
+                                               FALSE); /* task_objq locked? */
                        /*
                         * Set to VM_PURGABLE_EMPTY because the pages are no
                         * longer accounted in the "non-volatile" ledger
index 1ef57792db9f07735aa216875bebf683fb5a88c8..2474375718d03d4ba05a4e6b8243427f6b3e2262 100644 (file)
@@ -385,6 +385,7 @@ struct vm_object {
 #endif /* VM_PIP_DEBUG  */
 
         queue_chain_t          objq;      /* object queue - currently used for purgable queues */
+       queue_chain_t           task_objq; /* objects owned by task - protected by task lock */
 
 #if DEBUG
        void *purgeable_owner_bt[16];
@@ -671,7 +672,7 @@ __private_extern__ void     vm_object_reuse_pages(
        vm_object_offset_t      end_offset,
        boolean_t               allow_partial_reuse);
 
-__private_extern__ void                vm_object_purge(
+__private_extern__ uint64_t    vm_object_purge(
                                       vm_object_t              object,
                                       int                      flags);
 
index ada634f90184ce8c39a7c073eb578ffcfb778bb6..20eac579db3213c4f95b93b587350d47f057ebfa 100644 (file)
@@ -3236,14 +3236,14 @@ throttle_inactive:
                                        VM_DEBUG_CONSTANT_EVENT(vm_pageout_jetsam, VM_PAGEOUT_JETSAM, DBG_FUNC_START,
                                               vm_page_active_count, vm_page_inactive_count, vm_page_free_count, vm_page_free_count);
 
-                                        /* Kill first suitable process */
-                                       if (memorystatus_kill_on_VM_page_shortage(FALSE) == FALSE) {
-                                               panic("vm_pageout_scan: Jetsam request failed\n");      
+                                        /* Kill first suitable process. If this call returned FALSE, we might have simply purged a process instead. */
+                                       if (memorystatus_kill_on_VM_page_shortage(FALSE) == TRUE) {
+                                               vm_pageout_inactive_external_forced_jetsam_count++;
                                        }
                                        
-                                       VM_DEBUG_CONSTANT_EVENT(vm_pageout_jetsam, VM_PAGEOUT_JETSAM, DBG_FUNC_END, 0, 0, 0, 0);
+                                       VM_DEBUG_CONSTANT_EVENT(vm_pageout_jetsam, VM_PAGEOUT_JETSAM, DBG_FUNC_END,
+                                                       vm_page_active_count, vm_page_inactive_count, vm_page_free_count, vm_page_free_count);
 
-                                       vm_pageout_inactive_external_forced_jetsam_count++;
                                        vm_page_lock_queues();  
                                        delayed_unlock = 1;
                                }
@@ -5898,6 +5898,7 @@ REDISCOVER_ENTRY:
                                                  (entry->vme_end -
                                                   entry->vme_start)));
                VME_OFFSET_SET(entry, 0);
+               assert(entry->use_pmap);
 
                vm_map_lock_write_to_read(map);
        }
index de4756f67bfd3752004c291e41387de2e7eb8097..54781267b2cff0b569313e797dd8122f5ec25e89 100644 (file)
@@ -109,6 +109,12 @@ extern kern_return_t vm_map_purgable_control(
                                vm_purgable_t           control,
                                int                     *state);
 
+extern kern_return_t
+vnode_pager_get_object_vnode(
+       memory_object_t mem_obj,
+       uintptr_t * vnodeaddr,
+       uint32_t * vid);
+
 #if CONFIG_COREDUMP
 extern boolean_t coredumpok(vm_map_t map, vm_offset_t va);
 #endif
index a58b75001b99990e5041ce4bffcb9dc022cd416c..84abed964cf4dd4c1c952b795a4ed1c71f41ba74 100644 (file)
 
 #include <sys/kdebug.h>
 
+/*
+ * LOCK ORDERING for task-owned purgeable objects
+ *
+ * Whenever we need to hold multiple locks while adding to, removing from,
+ * or scanning a task's task_objq list of VM objects it owns, locks should
+ * be taken in this order:
+ *
+ * VM object ==> vm_purgeable_queue_lock ==> owner_task->task_objq_lock
+ *
+ * If one needs to acquire the VM object lock after any of the other 2 locks,
+ * one needs to use vm_object_lock_try() and, if that fails, release the
+ * other locks and retake them all in the correct order.
+ */
+
 extern vm_pressure_level_t memorystatus_vm_pressure_level;
 
 struct token {
@@ -1249,63 +1263,11 @@ vm_purgeable_account(
 }
 #endif /* DEVELOPMENT || DEBUG */
 
-static void
-vm_purgeable_volatile_queue_disown(
-       purgeable_q_t   queue,
-       int             group,
-       task_t          task)
-{
-       vm_object_t     object;
-       int             collisions;
-
-       collisions = 0;
-
-again:
-       LCK_MTX_ASSERT(&vm_purgeable_queue_lock, LCK_MTX_ASSERT_OWNED);
-
-       for (object = (vm_object_t) queue_first(&queue->objq[group]);
-            !queue_end(&queue->objq[group], (queue_entry_t) object);
-            object = (vm_object_t) queue_next(&object->objq)) {
-#if MACH_ASSERT
-               /*
-                * Sanity check: let's scan the entire queues to
-                * make sure we don't leave any purgeable objects
-                * pointing back at a dead task.  If the counters
-                * are off, we would fail to assert that they go
-                * back to 0 after disowning is done.
-                */
-#else /* MACH_ASSERT */
-               if (task->task_volatile_objects == 0) {
-                       /* no more volatile objects owned by "task" */
-                       break;
-               }
-#endif /* MACH_ASSERT */
-               if (object->vo_purgeable_owner == task) {
-                       if (! vm_object_lock_try(object)) {
-                               lck_mtx_unlock(&vm_purgeable_queue_lock);
-                               mutex_pause(collisions++);
-                               lck_mtx_lock(&vm_purgeable_queue_lock);
-                               goto again;
-                       }
-                       assert(object->purgable == VM_PURGABLE_VOLATILE);
-                       if (object->vo_purgeable_owner == task) {
-                               vm_purgeable_accounting(object,
-                                                       object->purgable,
-                                                       TRUE); /* disown */
-                               assert(object->vo_purgeable_owner == NULL);
-                       }
-                       vm_object_unlock(object);
-               }
-       }
-}
-
 void
 vm_purgeable_disown(
        task_t  task)
 {
-       purgeable_q_t   volatile_q;
-       int             group;
-       queue_head_t    *nonvolatile_q;
+       vm_object_t     next_object;
        vm_object_t     object;
        int             collisions;
 
@@ -1313,8 +1275,6 @@ vm_purgeable_disown(
                return;
        }
 
-       task->task_purgeable_disowning = TRUE;
-
        /*
         * Scan the purgeable objects queues for objects owned by "task".
         * This has to be done "atomically" under the "vm_purgeable_queue"
@@ -1335,73 +1295,55 @@ again:
                assert(task->task_nonvolatile_objects == 0);
                return;
        }
+
        lck_mtx_lock(&vm_purgeable_queue_lock);
+       task_objq_lock(task);
 
-       nonvolatile_q = &purgeable_nonvolatile_queue;
-       for (object = (vm_object_t) queue_first(nonvolatile_q);
-             !queue_end(nonvolatile_q, (queue_entry_t) object);
-            object = (vm_object_t) queue_next(&object->objq)) {
-#if MACH_ASSERT
-               /*
-                * Sanity check: let's scan the entire queues to
-                * make sure we don't leave any purgeable objects
-                * pointing back at a dead task.  If the counters
-                * are off, we would fail to assert that they go
-                * back to 0 after disowning is done.
-                */
-#else /* MACH_ASSERT */
-               if (task->task_nonvolatile_objects == 0) {
-                       /* no more non-volatile objects owned by "task" */
+       task->task_purgeable_disowning = TRUE;
+
+       for (object = (vm_object_t) queue_first(&task->task_objq);
+            !queue_end(&task->task_objq, (queue_entry_t) object);
+            object = next_object) {
+               if (task->task_nonvolatile_objects == 0 &&
+                   task->task_volatile_objects == 0) {
+                       /* no more purgeable objects owned by "task" */
                        break;
                }
-#endif /* MACH_ASSERT */
+
+               next_object = (vm_object_t) queue_next(&object->task_objq);
+               if (object->purgable == VM_PURGABLE_DENY) {
+                       /* not a purgeable object: skip */
+                       continue;
+               }
+
 #if DEBUG
                assert(object->vo_purgeable_volatilizer == NULL);
 #endif /* DEBUG */
-               if (object->vo_purgeable_owner == task) {
-                       if (!vm_object_lock_try(object)) {
-                               lck_mtx_unlock(&vm_purgeable_queue_lock);
-                               mutex_pause(collisions++);
-                               goto again;
-                       }
-                       if (object->vo_purgeable_owner == task) {
-                               vm_purgeable_accounting(object,
-                                                       object->purgable,
-                                                       TRUE); /* disown */
-                               assert(object->vo_purgeable_owner == NULL);
-                       }
-                       vm_object_unlock(object);
+               assert(object->vo_purgeable_owner == task);
+               if (!vm_object_lock_try(object)) {
+                       lck_mtx_unlock(&vm_purgeable_queue_lock);
+                       task_objq_unlock(task);
+                       mutex_pause(collisions++);
+                       goto again;
                }
+               vm_purgeable_accounting(object,
+                                       object->purgable,
+                                       TRUE, /* disown */
+                                       TRUE);/* task_objq_lock is locked */
+               assert(object->vo_purgeable_owner == NULL);
+               vm_object_unlock(object);
        }
 
-       lck_mtx_yield(&vm_purgeable_queue_lock);
-
-       /*
-        * Scan volatile queues for objects owned by "task".
-        */
-
-       volatile_q = &purgeable_queues[PURGEABLE_Q_TYPE_OBSOLETE];
-       vm_purgeable_volatile_queue_disown(volatile_q, 0, task);
-       lck_mtx_yield(&vm_purgeable_queue_lock);
-
-       volatile_q = &purgeable_queues[PURGEABLE_Q_TYPE_FIFO];
-       for (group = 0; group < NUM_VOLATILE_GROUPS; group++) {
-               vm_purgeable_volatile_queue_disown(volatile_q, group, task);
-               lck_mtx_yield(&vm_purgeable_queue_lock);
-       }
-       
-       volatile_q = &purgeable_queues[PURGEABLE_Q_TYPE_LIFO];
-       for (group = 0; group < NUM_VOLATILE_GROUPS; group++) {
-               vm_purgeable_volatile_queue_disown(volatile_q, group, task);
-               lck_mtx_yield(&vm_purgeable_queue_lock);
-       }
-
-       if (task->task_volatile_objects != 0 ||
-           task->task_nonvolatile_objects != 0) {
-               /* some purgeable objects sneaked into a queue: find them */
-               lck_mtx_unlock(&vm_purgeable_queue_lock);
-               mutex_pause(collisions++);
-               goto again;
+       if (__improbable(task->task_volatile_objects != 0 ||
+                        task->task_nonvolatile_objects != 0)) {
+               panic("%s(%p): volatile=%d nonvolatile=%d q=%p q_first=%p q_last=%p",
+                     __FUNCTION__,
+                     task,
+                     task->task_volatile_objects,
+                     task->task_nonvolatile_objects,
+                     &task->task_objq,
+                     queue_first(&task->task_objq),
+                     queue_last(&task->task_objq));
        }
 
        /* there shouldn't be any purgeable objects owned by task now */
@@ -1413,34 +1355,31 @@ again:
        task->task_purgeable_disowned = TRUE;
 
        lck_mtx_unlock(&vm_purgeable_queue_lock);
+       task_objq_unlock(task);
 }
 
 
-#if notyet
-static int
+static uint64_t
 vm_purgeable_queue_purge_task_owned(
        purgeable_q_t   queue,
        int             group,
        task_t          task)
 {
-       vm_object_t     object;
-       int             num_objects;
-       int             collisions;
-       int             num_objects_purged;
+       vm_object_t     object = VM_OBJECT_NULL;
+       int             collisions = 0;
+       uint64_t        num_pages_purged = 0;
 
-       num_objects_purged = 0;
+       num_pages_purged = 0;
        collisions = 0;
 
 look_again:
        lck_mtx_lock(&vm_purgeable_queue_lock);
 
-       num_objects = 0;
        for (object = (vm_object_t) queue_first(&queue->objq[group]);
             !queue_end(&queue->objq[group], (queue_entry_t) object);
             object = (vm_object_t) queue_next(&object->objq)) {
 
-               if (object->vo_purgeable_owner != task &&
-                   object->vo_purgeable_owner != NULL) {
+               if (object->vo_purgeable_owner != task) {
                        continue;
                }
 
@@ -1459,6 +1398,8 @@ look_again:
                             vm_object_t, objq);
                object->objq.next = NULL;
                object->objq.prev = NULL;
+               object->purgeable_queue_type = PURGEABLE_Q_TYPE_MAX;
+               object->purgeable_queue_group = 0;
                /* one less volatile object for this object's owner */
                assert(object->vo_purgeable_owner == task);
                vm_purgeable_volatile_owner_update(task, -1);
@@ -1486,11 +1427,11 @@ look_again:
                }
 
                /* purge the object */
-               (void) vm_object_purge(object, 0);
+               num_pages_purged += vm_object_purge(object, 0);
+
                assert(object->purgable == VM_PURGABLE_EMPTY);
                /* no change for purgeable accounting */
                vm_object_unlock(object);
-               num_objects_purged++;
 
                /* we unlocked the purgeable queues, so start over */
                goto look_again;
@@ -1498,39 +1439,38 @@ look_again:
 
        lck_mtx_unlock(&vm_purgeable_queue_lock);
 
-       return num_objects_purged;
+       return num_pages_purged;
 }
 
-int
+uint64_t
 vm_purgeable_purge_task_owned(
        task_t  task)
 {
-       purgeable_q_t   queue;
-       int             group;
-       int             num_objects_purged;
+       purgeable_q_t   queue = NULL;
+       int             group = 0;
+       uint64_t        num_pages_purged = 0;
 
-       num_objects_purged = 0;
+       num_pages_purged = 0;
 
        queue = &purgeable_queues[PURGEABLE_Q_TYPE_OBSOLETE];
-       num_objects_purged += vm_purgeable_queue_purge_task_owned(queue,
+       num_pages_purged += vm_purgeable_queue_purge_task_owned(queue,
                                                                  0,
                                                                  task);
 
        queue = &purgeable_queues[PURGEABLE_Q_TYPE_FIFO];
        for (group = 0; group < NUM_VOLATILE_GROUPS; group++)
-               num_objects_purged += vm_purgeable_queue_purge_task_owned(queue,
+               num_pages_purged += vm_purgeable_queue_purge_task_owned(queue,
                                                                          group,
                                                                          task);
        
        queue = &purgeable_queues[PURGEABLE_Q_TYPE_LIFO];
        for (group = 0; group < NUM_VOLATILE_GROUPS; group++)
-               num_objects_purged += vm_purgeable_queue_purge_task_owned(queue,
+               num_pages_purged += vm_purgeable_queue_purge_task_owned(queue,
                                                                          group,
                                                                          task);
 
-       return num_objects_purged;
+       return num_pages_purged;
 }
-#endif
 
 void
 vm_purgeable_nonvolatile_enqueue(
@@ -1556,6 +1496,11 @@ vm_purgeable_nonvolatile_enqueue(
 #if DEBUG
        object->vo_purgeable_volatilizer = NULL;
 #endif /* DEBUG */
+       if (owner != NULL) {
+               task_objq_lock(owner);
+               queue_enter(&owner->task_objq, object, vm_object_t, task_objq);
+               task_objq_unlock(owner);
+       }
 
 #if DEBUG
        OSBacktrace(&object->purgeable_owner_bt[0], 16);
@@ -1606,7 +1551,8 @@ vm_purgeable_nonvolatile_dequeue(
                 */
                vm_purgeable_accounting(object,
                                        object->purgable,
-                                       TRUE); /* disown */
+                                       TRUE, /* disown */
+                                       FALSE); /* is task_objq locked? */
        }
 
        lck_mtx_lock(&vm_purgeable_queue_lock);
@@ -1628,7 +1574,8 @@ void
 vm_purgeable_accounting(
        vm_object_t     object,
        vm_purgable_t   old_state,
-       boolean_t       disown)
+       boolean_t       disown,
+       boolean_t       task_objq_locked)
 {
        task_t          owner;
        int             resident_page_count;
@@ -1693,6 +1640,15 @@ vm_purgeable_accounting(
                                vm_purgeable_volatile_owner_update(owner, -1);
                        }
                        /* no more accounting for this dead object */
+                       owner = object->vo_purgeable_owner;
+                       if (! task_objq_locked) {
+                               task_objq_lock(owner);
+                       }
+                       task_objq_lock_assert_owned(owner);
+                       queue_remove(&owner->task_objq, object, vm_object_t, task_objq);
+                       if (! task_objq_locked) {
+                               task_objq_unlock(owner);
+                       }
                        object->vo_purgeable_owner = NULL;
 #if DEBUG
                        object->vo_purgeable_volatilizer = NULL;
@@ -1748,6 +1704,14 @@ vm_purgeable_accounting(
                        }
                        vm_purgeable_nonvolatile_owner_update(owner, -1);
                        /* no more accounting for this dead object */
+                       if (! task_objq_locked) {
+                               task_objq_lock(owner);
+                       }
+                       task_objq_lock_assert_owned(owner);
+                       queue_remove(&owner->task_objq, object, vm_object_t, task_objq);
+                       if (! task_objq_locked) {
+                               task_objq_unlock(owner);
+                       }
                        object->vo_purgeable_owner = NULL;
 #if DEBUG
                        object->vo_purgeable_volatilizer = NULL;
index c982a6307c2e43e481b4500c507298ab1fae4391..010c2ee227e622663690c7c8976cd86fadf6132b 100644 (file)
@@ -119,12 +119,13 @@ void vm_purgeable_stats(vm_purgeable_info_t info, task_t target_task);
 kern_return_t vm_purgeable_account(task_t task, pvm_account_info_t acnt_info);
 #endif /* DEVELOPMENT || DEBUG */
 
-int vm_purgeable_purge_task_owned(task_t task);
+uint64_t vm_purgeable_purge_task_owned(task_t task);
 void vm_purgeable_nonvolatile_enqueue(vm_object_t object, task_t task);
 void vm_purgeable_nonvolatile_dequeue(vm_object_t object);
 void vm_purgeable_accounting(vm_object_t       object,
                             vm_purgable_t      old_state,
-                            boolean_t          disown);
+                            boolean_t          disown,
+                            boolean_t          task_objq_locked);
 void vm_purgeable_compressed_update(vm_object_t        object,
                                    int         delta);
 
index 2f9bdc101c6699fb9a829fefc355f6cfbe93efc7..f199dd4feeeb1ce1fd9e952ada6ddbc98d5f8acd 100644 (file)
@@ -2912,6 +2912,7 @@ redo_lookup:
                                                (VME_OFFSET(next_entry->vme_prev) +
                                                 (next_entry->vme_prev->vme_end 
                                                  - next_entry->vme_prev->vme_start)));
+                                       next_entry->use_pmap = TRUE;
                                                next_entry->needs_copy = FALSE;
                                        } else {
                                                panic("mach_make_memory_entry_64:"
@@ -3248,6 +3249,20 @@ task_wire(
        return(KERN_SUCCESS);
 }
 
+kern_return_t
+vm_map_exec_lockdown(
+       vm_map_t        map)
+{
+       if (map == VM_MAP_NULL)
+               return(KERN_INVALID_ARGUMENT);
+
+       vm_map_lock(map);
+       map->map_disallow_new_exec = TRUE;
+       vm_map_unlock(map);
+
+       return(KERN_SUCCESS);
+}
+
 __private_extern__ kern_return_t
 mach_memory_entry_allocate(
        vm_named_entry_t        *user_entry_p,
index 8cd909bbb87c0daee3ae7bb01459a7fec5ceeea0..3ed02246fcf16090ceaf64882a5fc51d334ca210 100644 (file)
@@ -63,7 +63,7 @@
 /*
  * Note: memcpy does not support overlapping copies
        */
-       /* TODO: movsb */
+
 ENTRY(memcpy)
        movq    %rdi, %rax                      /* return destination */
        movq    %rdx,%rcx
index 13f3f021802880fe6a8778ec44f08c61a1a3af2c..0996137ba0745e938163cc47739d573473a02ac1 100644 (file)
@@ -237,13 +237,33 @@ Entry(idt64_mc)
  * This may or may not be fatal but extreme care is required
  * because it may fall when control was already in another trampoline.
  *
- * We get here on IST2 stack which is used for NMIs only.
+ * We get here on IST2 stack which is used exclusively for NMIs.
+ * Machine checks, doublefaults and similar use IST1
  */
 Entry(idt64_nmi)
-       push    %rax                            /* save RAX to ISF64_ERR */
-       push    %rcx                            /* save RCX to ISF64_TRAPFN */
-       push    %rdx                            /* save RDX to ISF64_TRAPNO */
-       jmp     L_dispatch
+       /* Synthesize common interrupt stack frame */
+       pushq   $0
+       pushq   $(HNDL_ALLINTRS)
+       pushq   $(T_NMI)
+       /* Spill prior to RDMSR */
+       push    %rax
+       push    %rcx
+       push    %rdx
+       mov     $(MSR_IA32_GS_BASE), %ecx
+       rdmsr                                   /* Check contents of GSBASE MSR */
+       test    $0x80000000, %edx               /* MSB set? Already swapped to kernel's */
+       jnz     44f
+       swapgs                                  /* Either direct from user or within trampolines */
+44:
+       pop     %rdx
+       pop     %rcx
+
+       leaq    EXT(idt64_hndl_table0)(%rip), %rax
+       mov     16(%rax), %rax /* Offset of per-CPU shadow */
+       mov     %gs:CPU_KERNEL_CR3(%rax), %rax
+       mov     %rax, %cr3 /* Unconditionally switch to primary kernel pagetables */
+       leaq    EXT(idt64_hndl_table0)(%rip), %rax
+       jmp     *(%rax)
 
 Entry(idt64_double_fault)
        pushq   $(HNDL_DOUBLE_FAULT)
@@ -474,6 +494,17 @@ L_dispatch_64bit:
        mov     %r13, R64_R13(%r15)
        mov     %r14, R64_R14(%r15)
 
+       /* Zero unused GPRs. BX/DX/SI are clobbered elsewhere across the exception handler, and are skipped. */
+       xor     %ecx, %ecx
+       xor     %edi, %edi
+       xor     %r8, %r8
+       xor     %r9, %r9
+       xor     %r10, %r10
+       xor     %r11, %r11
+       xor     %r12, %r12
+       xor     %r13, %r13
+       xor     %r14, %r14
+
        /* cr2 is significant only for page-faults */
        mov     %cr2, %rax
        mov     %rax, R64_CR2(%r15)
@@ -528,6 +559,16 @@ L_dispatch_U32: /* 32-bit user task */
        /* Unconditionally save cr2; only meaningful on page faults */
        mov     %cr2, %rax
        mov     %eax, R32_CR2(%r15)
+       /* Zero unused GPRs. BX/DX/SI/R15 are clobbered elsewhere across the exception handler, and are skipped. */
+       xor     %ecx, %ecx
+       xor     %edi, %edi
+       xor     %r8, %r8
+       xor     %r9, %r9
+       xor     %r10, %r10
+       xor     %r11, %r11
+       xor     %r12, %r12
+       xor     %r13, %r13
+       xor     %r14, %r14
 
        /*
         * Copy registers already saved in the machine state 
@@ -606,6 +647,13 @@ L_common_dispatch:
 5:
        incl    %gs:hwIntCnt(,%ebx,4)           // Bump the trap/intr count
        /* Dispatch the designated handler */
+       cmp     EXT(dblmap_base)(%rip), %rsp
+       jb      66f
+       cmp     EXT(dblmap_max)(%rip), %rsp
+       jge     66f
+       subq    EXT(dblmap_dist)(%rip), %rsp
+       subq    EXT(dblmap_dist)(%rip), %r15
+66:
        leaq    EXT(idt64_hndl_table1)(%rip), %rax
        jmp     *(%rax, %rdx, 8)
 
@@ -749,6 +797,7 @@ L_32bit_return:
        mov     %r15, %rsp              /* Set the PCB as the stack */
        swapgs
 
+       /* Zero 64-bit-exclusive GPRs to prevent data leaks */
        xor     %r8, %r8
        xor     %r9, %r9
        xor     %r10, %r10
@@ -1510,13 +1559,9 @@ Entry(hndl_diag_scall64)
 /* TODO assert at all 'C' entry points that we're never operating on the fault stack's alias mapping */
 Entry(hndl_machine_check)
        /* Adjust SP and savearea to their canonical, non-aliased addresses */
-       subq    EXT(dblmap_dist)(%rip), %rsp
-       subq    EXT(dblmap_dist)(%rip), %r15
        CCALL1(panic_machine_check64, %r15)
        hlt
 
 Entry(hndl_double_fault)
-       subq    EXT(dblmap_dist)(%rip), %rsp
-       subq    EXT(dblmap_dist)(%rip), %r15
        CCALL1(panic_double_fault64, %r15)
        hlt
index 4da5d98097e3dc75a3b0d5c0d63f96ae0f1c6b26..a34b77fb3c8bc30dee4c32fcd61c5f01fe3fd300 100644 (file)
 #include <kperf/context.h>
 #include <kperf/action.h>
 
-#include <chud/chud_xnu.h>
-
-
-
 /* Fixed counter mask -- three counters, each with OS and USER */
 #define IA32_FIXED_CTR_ENABLE_ALL_CTRS_ALL_RINGS (0x333)
 #define IA32_FIXED_CTR_ENABLE_ALL_PMI (0x888)
index cde29d95503a137ada336e07060159e8a924f91a..4ed3792b82578d341ffde8037f87591bfaae3c5c 100644 (file)
@@ -53,7 +53,7 @@ typedef struct lowglo {
        uint64_t        lgZero;                 /* 0xffffff8000002008 Double constant 0 */
        uint64_t        lgStext;                /* 0xffffff8000002010 Start of kernel text */
        uint64_t        lgRsv018;               /* 0xffffff8000002018 Reserved */
-       uint64_t        lgCHUDXNUfnStart;       /* 0xffffff8000002020 CHUD XNU function glue table */
+       uint64_t        lgRsv020;               /* 0xffffff8000002020 Reserved */
        uint64_t        lgRsv028;               /* 0xffffff8000002028 Reserved */
        uint64_t        lgVersion;              /* 0xffffff8000002030 Pointer to kernel version string */
        uint64_t        lgRsv038[280];          /* 0xffffff8000002038 Reserved */
index 190edafc1a608f9c22c06ee512ca2bcb81ba3269..09bd405e449340b6eb4b2aa80512ed050e4e6f17 100644 (file)
@@ -76,8 +76,6 @@ lowglo lowGlo __attribute__ ((aligned(PAGE_SIZE))) = {
 
        .lgVerCode              = { 'C','a','t','f','i','s','h',' ' },
 
-       .lgCHUDXNUfnStart       = 0,
-
        .lgVersion              = (uint64_t) &version,
 
        .lgKmodptr              = (uint64_t) &kmod,
index ce64b82dbf1486c193fa2f6e54166b4de75cc8d7..852b7618dc9ef197734c5b3c528c9fa4467b82dc 100644 (file)
@@ -331,6 +331,7 @@ pmap_cpu_init(void)
         * Initialize the per-cpu, TLB-related fields.
         */
        cdp->cpu_kernel_cr3 = kernel_pmap->pm_cr3;
+       cpu_shadowp(cdp->cpu_number)->cpu_kernel_cr3 = cdp->cpu_kernel_cr3;
        cdp->cpu_active_cr3 = kernel_pmap->pm_cr3;
        cdp->cpu_tlb_invalid = FALSE;
        cdp->cpu_task_map = TASK_MAP_64BIT;
@@ -421,7 +422,7 @@ pmap_bootstrap(
 
        pmap_pcid_initialize_kernel(kernel_pmap);
 
-       current_cpu_datap()->cpu_kernel_cr3 = (addr64_t) kernel_pmap->pm_cr3;
+       current_cpu_datap()->cpu_kernel_cr3 = cpu_shadowp(cpu_number())->cpu_kernel_cr3 = (addr64_t) kernel_pmap->pm_cr3;
 
        nkpt = NKPT;
        OSAddAtomic(NKPT,  &inuse_ptepages_count);
@@ -2518,7 +2519,7 @@ pmap_flush(
 
                        cpus_to_signal &= ~cpu_bit;
 
-                       if (!cpu_datap(cpu)->cpu_running)
+                       if (!cpu_is_running(cpu))
                                continue;
 
                        if (pfc->pfc_invalid_global & cpu_bit)
@@ -2563,7 +2564,7 @@ pmap_flush(
                                 * as appropriate in the PCID case.
                                 */
                                if ((cpus_to_respond & cpu_bit) != 0) {
-                                       if (!cpu_datap(cpu)->cpu_running ||
+                                       if (!cpu_is_running(cpu) ||
                                            cpu_datap(cpu)->cpu_tlb_invalid == FALSE ||
                                            !CPU_CR3_IS_ACTIVE(cpu)) {
                                                cpus_to_respond &= ~cpu_bit;
@@ -2678,7 +2679,7 @@ pmap_flush_tlbs(pmap_t    pmap, vm_map_offset_t startv, vm_map_offset_t endv, int o
                mfence();
        }
        for (cpu = 0, cpu_bit = 1; cpu < real_ncpus; cpu++, cpu_bit <<= 1) {
-               if (!cpu_datap(cpu)->cpu_running)
+               if (!cpu_is_running(cpu))
                        continue;
                uint64_t        cpu_active_cr3 = CPU_GET_ACTIVE_CR3(cpu);
                uint64_t        cpu_task_cr3 = CPU_GET_TASK_CR3(cpu);
@@ -2764,7 +2765,7 @@ pmap_flush_tlbs(pmap_t    pmap, vm_map_offset_t startv, vm_map_offset_t endv, int o
                                 * as appropriate in the PCID case.
                                 */
                                if ((cpus_to_respond & cpu_bit) != 0) {
-                                       if (!cpu_datap(cpu)->cpu_running ||
+                                       if (!cpu_is_running(cpu) ||
                                            cpu_datap(cpu)->cpu_tlb_invalid == FALSE ||
                                            !CPU_CR3_IS_ACTIVE(cpu)) {
                                                cpus_to_respond &= ~cpu_bit;
index 103a1bb90c5940acb23ae28c9f2179c4dab5aee6..28732b8b51e8b955375bcdfa035320c649dee0e4 100644 (file)
@@ -1,12 +1,29 @@
 /*
- * Copyright (C) 2011-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2018 Apple Inc. All rights reserved.
  *
- * This document is the property of Apple Inc.
- * It is considered confidential and proprietary.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * This document may not be reproduced or transmitted in any form,
- * in whole or in part, without the express written permission of
- * Apple Inc.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <pexpert/pexpert.h>
index ff4a301e20f70d790c238127ed682468f8bce057..6b9000117a1cdd805f0419fb59ee8866a9d80507 100644 (file)
@@ -644,10 +644,9 @@ static void dockchannel_uart_init(void)
        // Setup DRAIN timer
        rDOCKCHANNELS_DEV_DRAIN_CFG(DOCKCHANNEL_UART_CHANNEL) = max_dockchannel_drain_period;
 
-       // Drain timer doesnt get loaded with value from drain period register if fifo
-       // is already full. Drop a character from the fifo. 
-       // Refer https://seg-docs.ecs.apple.com/projects/cayman//release/specs/Apple/DockChannels/DockChannels_Specification.pdf
-       // Chapter 8 for more details.
+       // Drain timer doesn't get loaded with value from drain period register if fifo
+       // is already full. Drop a character from the fifo.  See chapter 8 of the Cayman
+       // DockChannels specification for more details.
        rDOCKCHANNELS_DOCK_RDATA1(DOCKCHANNEL_UART_CHANNEL);
 }
 
index 91a10f867f8e7196a9d6b90c89286882fd72e43a..94818a6148a5d0c38c0f6f33d84f0c3bcde7ad05 100644 (file)
@@ -48,6 +48,12 @@ static struct pe_serial_functions *gPESF;
 
 static int uart_initted = 0;   /* 1 if init'ed */
 
+static unsigned int legacy_uart_enabled = 0; /* 1 Legacy IO based UART is supported on platform */
+
+static boolean_t lpss_uart_supported = 0; /* 1 if LPSS UART is supported on platform */
+static unsigned int lpss_uart_enabled = 0; /* 1 if it is LPSS UART is in D0 state */
+static void lpss_uart_re_init (void);
+
 #define DEFAULT_UART_BAUD_RATE 115200
 
 static unsigned uart_baud_rate = DEFAULT_UART_BAUD_RATE;
@@ -103,6 +109,11 @@ enum {
     UART_LSR_THRE  = 0x20
 };
 
+enum {
+       UART_CLK_125M_1 = 0x60002,
+       UART_CLK_125M_2 = 0x80060003,
+};
+
 static int
 legacy_uart_probe( void )
 {
@@ -207,8 +218,9 @@ static struct pe_serial_functions legacy_uart_serial_functions = {
 // MMIO UART (using PCH LPSS UART2)
 // =============================================================================
 
-#define MMIO_UART2_BASE_LEGACY  0xFE034000
-#define MMIO_UART2_BASE         0xFE036000
+#define MMIO_UART2_BASE_LEGACY  0xFE034000 /* Legacy MMIO Config space */
+#define MMIO_UART2_BASE         0xFE036000 /* MMIO Config space */
+#define PCI_UART2               0xFE037000 /* PCI Config Space */
 
 #define MMIO_WRITE(r, v)  ml_phys_write_word(mmio_uart_base + MMIO_UART_##r, v)
 #define MMIO_READ(r)      ml_phys_read_word(mmio_uart_base + MMIO_UART_##r)
@@ -223,7 +235,9 @@ enum {
     MMIO_UART_LCR = 0xc,   /* line control register         */
     MMIO_UART_MCR = 0x10,  /* modem control register        */
     MMIO_UART_LSR = 0x14,  /* line status register          */
-    MMIO_UART_SCR = 0x1c   /* scratch register              */
+    MMIO_UART_SCR = 0x1c,  /* scratch register              */
+    MMIO_UART_CLK = 0x200, /* clocks register               */
+    MMIO_UART_RST = 0x204  /* Reset register              */
 };
 
 static vm_offset_t mmio_uart_base = 0;
@@ -235,7 +249,6 @@ mmio_uart_present( void )
     if (MMIO_READ(SCR) != 0x5a) return 0;
     MMIO_WRITE( SCR, 0xa5 );
     if (MMIO_READ(SCR) != 0xa5) return 0;
-
     return 1;
 }
 
@@ -348,6 +361,63 @@ mmio_uart_rr0( void )
     return (lsr & UART_LSR_DR);
 }
 
+void lpss_uart_enable( boolean_t on_off )
+{
+       unsigned int pmcs_reg;
+
+       if (!lpss_uart_supported) {
+               return;
+       }
+
+       pmcs_reg = ml_phys_read_byte (PCI_UART2 + 0x84);
+       if (on_off == FALSE) {
+               pmcs_reg |= 0x03;
+               lpss_uart_enabled = 0;
+       } else {
+               pmcs_reg &= ~(0x03);
+       }
+
+       ml_phys_write_byte (PCI_UART2 + 0x84, pmcs_reg);
+       pmcs_reg = ml_phys_read_byte (PCI_UART2 + 0x84);
+       
+       if (on_off == TRUE) {
+               lpss_uart_re_init();
+               lpss_uart_enabled = 1;
+       }
+}
+
+static void lpss_uart_re_init( void )
+{
+       uint32_t register_read;
+       
+       MMIO_WRITE (RST, 0x7);                          /* LPSS UART2 controller out ot reset */
+       register_read = MMIO_READ (RST);
+
+       MMIO_WRITE (LCR, UART_LCR_DLAB);        /* Set DLAB bit to enable reading/writing of DLL, DLH */
+       register_read = MMIO_READ (LCR);
+
+       MMIO_WRITE (DLL, 1);                            /* Divisor Latch Low Register */
+       register_read = MMIO_READ (DLL);
+
+       MMIO_WRITE (DLM, 0);                            /* Divisor Latch High Register */
+       register_read = MMIO_READ (DLM);
+
+       MMIO_WRITE (FCR, 1);                            /* Enable FIFO */
+       register_read = MMIO_READ (FCR);
+
+       MMIO_WRITE (LCR, UART_LCR_8BITS);       /* Set 8 bits, clear DLAB */
+       register_read = MMIO_READ (LCR);
+
+       MMIO_WRITE (MCR, UART_MCR_RTS);         /* Request to send */
+       register_read = MMIO_READ (MCR);
+
+       MMIO_WRITE (CLK, UART_CLK_125M_1);      /* 1.25M Clock speed */
+       register_read = MMIO_READ (CLK);
+
+       MMIO_WRITE (CLK, UART_CLK_125M_2);      /* 1.25M Clock speed */
+       register_read = MMIO_READ (CLK);        
+}
+
 static int
 mmio_uart_rd0( void ) 
 {
@@ -384,12 +454,15 @@ serial_init( void )
     {
         gPESF = &mmio_uart_serial_functions;
         gPESF->uart_init();
+        lpss_uart_supported = 1;
+        lpss_uart_enabled = 1;
         return 1;
     }
     else if ( legacy_uart_probe() )
     {
         gPESF = &legacy_uart_serial_functions;
         gPESF->uart_init();
+        legacy_uart_enabled = 1;
         return 1;
     }
     else
@@ -402,7 +475,7 @@ serial_init( void )
 static void
 uart_putc(char c)
 {
-    if (uart_initted) {
+       if (uart_initted && (legacy_uart_enabled || lpss_uart_enabled)) {
         while (!gPESF->tr0());  /* Wait until THR is empty. */
         gPESF->td0(c);
     }
@@ -411,7 +484,7 @@ uart_putc(char c)
 static int
 uart_getc(void)
 {
-    if (uart_initted) {
+    if (uart_initted && (legacy_uart_enabled || lpss_uart_enabled)) {
         if (!gPESF->rr0())
             return -1;
         return gPESF->rd0();
index 44b1fd4dac37a638e217f61d88785df758d5e9d8..e1c6e60733cf9faf7785f7295386d3b62bf5f24e 100644 (file)
@@ -26,7 +26,7 @@
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
- *  appleboot.h - Apple logo shown durring boot
+ *  appleboot.h - Apple logo shown during boot
  *
  *  Copyright (c) 2002 Apple Computer, Inc.
  *
index 97cf27cf0903614e671e908d6c3bbd4ba528f3a0..3697cd093da73448380729a6a202272239a7a7e0 100644 (file)
@@ -1,13 +1,31 @@
 /*
- * Copyright (C) 2011-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2018 Apple Inc. All rights reserved.
  *
- * This document is the property of Apple Inc.
- * It is considered confidential and proprietary.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * This document may not be reproduced or transmitted in any form,
- * in whole or in part, without the express written permission of
- * Apple Inc.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
+
 #ifndef PE_CONSISTENT_DEBUG_H
 #define PE_CONSISTENT_DEBUG_H
 
index 51ff2c59ae4c21ae9846e4ae04b8b587bd88877f..7b24690b9c3f1eef1743b8eb48b6f86be4ba4c59 100644 (file)
@@ -34,6 +34,8 @@
 #define ARM64_REG_EHID3_DisDcZvaCmdOnly                        (1<<25)
 
 #define ARM64_REG_HID4                                         S3_0_c15_c4_0
+#define ARM64_REG_EHID4                                                S3_0_c15_c4_1
+
 #define ARM64_REG_HID4_DisDcMVAOps                             (1<<11)
 #define ARM64_REG_HID4_DisSpecLnchRead                 (1<<33)
 #define ARM64_REG_HID4_ForceNsOrdLdReqNoOlderLd                        (1<<39)
@@ -81,6 +83,7 @@
 
 #if defined(APPLECYCLONE) || defined(APPLETYPHOON) || defined(APPLETWISTER)
 #define ARM64_REG_CYC_CFG                                      S3_5_c15_c4_0
+#define ARM64_REG_CYC_CFG_skipInit                             (1ULL<<30)
 #define ARM64_REG_CYC_CFG_deepSleep                            (1ULL<<24)
 #else
 #define ARM64_REG_ACC_OVRD                                     S3_5_c15_c6_0
 
 
 
-
 #endif /* APPLE_ARM64_ARCH_FAMILY */
 
 
 
 
 
+#define MPIDR_PNE_SHIFT                       16       // pcore not ecore
+#define MPIDR_PNE                      (1 << MPIDR_PNE_SHIFT)
+
+#ifdef ASSEMBLER
+
+/*
+ *  arg0: register in which to store result
+ *      0=>not a p-core, non-zero=>p-core
+ */
+.macro ARM64_IS_PCORE
+.endmacro
+
+/*
+ * reads a special purpose register, using a different msr for e- vs. p-cores
+ * arg0: register indicating the current core type, see ARM64_IS_PCORE
+ * arg1: register in which to store the result of the read
+ * arg2: SPR to use for e-core
+ * arg3: SPR to use for p-core or non-AMP architecture
+ */
+.macro ARM64_READ_EP_SPR
+       mrs             $1, $3
+2:
+.endmacro
+
+/*
+ * writes a special purpose register, using a different msr for e- vs. p-cores
+ * arg0: register indicating the current core type, see ARM64_IS_PCORE
+ * arg1: register containing the value to write
+ * arg2: SPR to use for e-core
+ * arg3: SPR to use for p-core or non-AMP architecture
+ */
+.macro ARM64_WRITE_EP_SPR
+       msr             $3, $1
+2:
+.endmacro
+
+#endif /* ASSEMBLER */
+
 #endif /* ! _PEXPERT_ARM_ARM64_H */
index 61ac16c9ca348a209c8a0327cd4589437831a9c8..eac7336cf0e37f6724836a186d3031deaf7beca8 100644 (file)
@@ -70,6 +70,8 @@ extern struct macos_panic_header *panic_info;
 #endif /* CONFIG_EMBEDDED */
 #endif /* XNU_KERNEL_PRIVATE */
 
+extern void lpss_uart_enable (boolean_t on_off);
+
 void PE_enter_debugger(
        const char *cause);
 
index 122be1c84311188b420a2cc92912971f4acc8199..864ea94246035386b25b5b315b49bb4725754969 100644 (file)
@@ -91,11 +91,14 @@ ___asan_alloca_poison
 ___asan_allocas_unpoison
 ___asan_register_globals
 ___asan_unregister_globals
+___asan_register_elf_globals
+___asan_unregister_elf_globals
 ___asan_register_image_globals
 ___asan_unregister_image_globals
 ___asan_version_mismatch_check_v8
 ___asan_version_mismatch_check_apple_802
 ___asan_version_mismatch_check_apple_900
+___asan_version_mismatch_check_apple_902
 ___asan_init
 ___asan_memcpy
 ___asan_memmove
index a2f25e8bce1905bb63bf9f4376c094ea133454b3..75a98ec4cc98c45629f0907055f9d1be6b2cdcd3 100644 (file)
@@ -30,12 +30,13 @@ INSTALL_MI_DIR = san
 EXPORT_MI_DIR = san
 COMP_SUBDIRS = conf
 
+.DELETE_ON_ERROR:
 $(OBJROOT)/san/kasan-blacklist-%: $(SOURCE)/kasan-blacklist $(SOURCE)/kasan-blacklist-%
        @echo "$(ColorH)GENERATING$(Color0)    $(ColorLF)$(notdir $@)$(Color0)"
        $(_v)sed -e 's,^src:\./,src:'"$(SRCROOT)/," $^ > $@
+       $(_v)$(SOURCE)/tools/validate_blacklist.sh "$@"
 
-do_build_setup:: $(OBJROOT)/san/kasan-blacklist-x86_64
-
+do_build_setup:: $(OBJROOT)/san/kasan-blacklist-x86_64 $(OBJROOT)/san/kasan-blacklist-arm64
 
 #
 # Kasan System.kext plugin
index 03e60fa814bfe62f3961f80c0a10b4255065fe90..5edceed1713dbe255a1253edd53eb0a7c4849fee 100644 (file)
@@ -13,7 +13,7 @@ export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
 include $(MakeInc_cmd)
 include $(MakeInc_def)
 
-CFLAGS+=
+CFLAGS += -Wassign-enum -Wswitch-enum
 
 #
 # Directories for mig generated files
index 22bb738a17d70f3f8cc4af519e65a94dae6a02a5..77ee449a803c5ba6623a6a8085c1b36092d03706 100644 (file)
@@ -69,10 +69,6 @@ extern vm_offset_t excepstack, excepstack_top;
 void kasan_bootstrap(boot_args *, vm_offset_t pgtable);
 void flush_mmu_tlb(void);
 
-#ifndef __ARM_16K_PG__
-#error "Unsupported HW config: Assuming 16K pages"
-#endif
-
 #define KASAN_SHIFT_ARM64 0xdffffff800000000ULL /* Defined in makedefs/MakeInc.def */
 #define KASAN_SHADOW_MIN  0xfffffff400000000ULL
 #define KASAN_SHADOW_MAX  0xfffffff680000000ULL
@@ -115,25 +111,18 @@ align_to_page(vm_offset_t *addrp, vm_offset_t *sizep)
 static void
 kasan_map_shadow_internal(vm_offset_t address, vm_size_t size, bool is_zero, bool back_page)
 {
-       align_to_page(&address, &size);
-
-       vm_size_t j;
-       uint64_t *pte;
+       vm_offset_t shadow_base = vm_map_trunc_page(SHADOW_FOR_ADDRESS(address), ARM_PGMASK);
+       vm_offset_t shadow_top = vm_map_round_page(SHADOW_FOR_ADDRESS(address + size), ARM_PGMASK);
 
-       /* XXX: this could be more efficient by walking through the shadow pages
-        * instead of the source pages */
-
-       for (j = 0; j < size; j += ARM_PGBYTES) {
-               vm_offset_t virt_shadow_target = (vm_offset_t)SHADOW_FOR_ADDRESS(address + j);
-
-               assert(virt_shadow_target >= KASAN_SHADOW_MIN);
-               assert(virt_shadow_target < KASAN_SHADOW_MAX);
+       assert(shadow_base >= KASAN_SHADOW_MIN && shadow_top <= KASAN_SHADOW_MAX);
 
+       for (; shadow_base < shadow_top; shadow_base += ARM_PGBYTES) {
                uint64_t *base = cpu_tte;
+               uint64_t *pte;
 
 #if !__ARM64_TWO_LEVEL_PMAP__
                /* lookup L1 entry */
-               pte = base + ((virt_shadow_target & ARM_TT_L1_INDEX_MASK) >> ARM_TT_L1_SHIFT);
+               pte = base + ((shadow_base & ARM_TT_L1_INDEX_MASK) >> ARM_TT_L1_SHIFT);
                if (*pte & ARM_TTE_VALID) {
                        assert((*pte & ARM_TTE_TYPE_MASK) == ARM_TTE_TYPE_TABLE);
                } else {
@@ -144,7 +133,7 @@ kasan_map_shadow_internal(vm_offset_t address, vm_size_t size, bool is_zero, boo
 #endif
 
                /* lookup L2 entry */
-               pte = base + ((virt_shadow_target & ARM_TT_L2_INDEX_MASK) >> ARM_TT_L2_SHIFT);
+               pte = base + ((shadow_base & ARM_TT_L2_INDEX_MASK) >> ARM_TT_L2_SHIFT);
                if (*pte & ARM_TTE_VALID) {
                        assert((*pte & ARM_TTE_TYPE_MASK) == ARM_TTE_TYPE_TABLE);
                } else {
@@ -158,7 +147,7 @@ kasan_map_shadow_internal(vm_offset_t address, vm_size_t size, bool is_zero, boo
                }
 
                /* lookup L3 entry */
-               pte = base + ((virt_shadow_target & ARM_TT_L3_INDEX_MASK) >> ARM_TT_L3_SHIFT);
+               pte = base + ((shadow_base & ARM_TT_L3_INDEX_MASK) >> ARM_TT_L3_SHIFT);
                if ((*pte & ARM_PTE_TYPE_VALID) &&
                    ((((*pte) & ARM_PTE_APMASK) != ARM_PTE_AP(AP_RONA)) || is_zero)) {
                        /* nothing to do - page already mapped and we are not
@@ -274,8 +263,6 @@ kasan_map_shadow_early(vm_offset_t address, vm_size_t size, bool is_zero)
 void
 kasan_arch_init(void)
 {
-       assert(KASAN_SHADOW_MIN >= VM_MAX_KERNEL_ADDRESS);
-
        /* Map the physical aperture */
        kasan_map_shadow(kernel_vtop, physmap_vtop - kernel_vtop, true);
 
@@ -331,3 +318,37 @@ kasan_bootstrap(boot_args *args, vm_offset_t pgtable)
        kasan_map_shadow_early(intstack_virt, intstack_size, false);
        kasan_map_shadow_early(excepstack_virt, excepstack_size, false);
 }
+
+bool
+kasan_is_shadow_mapped(uintptr_t shadowp)
+{
+       uint64_t *pte;
+       uint64_t *base = cpu_tte;
+
+       assert(shadowp >= KASAN_SHADOW_MIN);
+       assert(shadowp < KASAN_SHADOW_MAX);
+
+#if !__ARM64_TWO_LEVEL_PMAP__
+       /* lookup L1 entry */
+       pte = base + ((shadowp & ARM_TT_L1_INDEX_MASK) >> ARM_TT_L1_SHIFT);
+       if (!(*pte & ARM_TTE_VALID)) {
+               return false;
+       }
+       base = (uint64_t *)phystokv(*pte & ARM_TTE_TABLE_MASK);
+#endif
+
+       /* lookup L2 entry */
+       pte = base + ((shadowp & ARM_TT_L2_INDEX_MASK) >> ARM_TT_L2_SHIFT);
+       if (!(*pte & ARM_TTE_VALID)) {
+               return false;
+       }
+       base = (uint64_t *)phystokv(*pte & ARM_TTE_TABLE_MASK);
+
+       /* lookup L3 entry */
+       pte = base + ((shadowp & ARM_TT_L3_INDEX_MASK) >> ARM_TT_L3_SHIFT);
+       if (!(*pte & ARM_PTE_TYPE_VALID)) {
+               return false;
+       }
+
+       return true;
+}
index 5832fc0e1d69cc26caad62fd959f77dcf1d31bcd..cbef48e41e1a7fb10bdcee9aaf51f853fd6e5adc 100644 (file)
@@ -14,10 +14,19 @@ src:./san/kasan-x86_64.c
 src:./san/kasan-memintrinsics.c
 src:./san/kasan_dynamic_blacklist.c
 
+# Blanket ignore non-sanitized functions
+fun:__nosan_*
+
 # Try really hard to avoid panicing while debugging
 src:./osfmk/kdp/*
 src:./osfmk/kern/debug.c
 
+# Exclude dtrace function that does weird stack manipulations
+fun:fbt_perfCallback
+
+# Exclude leak detection code that reads all memory
+fun:_ZL18IOTrackingLeakScanPv
+
 # Exclude KASAN dependencies
 # XXX: could this be relaxed since fakestack is reentrant?
 src:./osfmk/kern/zalloc.c
index d91dac4a83cf4335076e90376e6869adcf6e85a4..9ef0c3aabc8b8cd65ee42b84ef6396a3049ef0e7 100644 (file)
@@ -3,8 +3,9 @@
 # Exclude KASan runtime
 src:./san/kasan-arm64.c
 
-# Uses a local to work out if we're on the interrupt stack, but ends up with a
-# fakestack allocation
+# These use a local variable to work out which stack we're on, but can end up with
+# a fakestack allocation.
 fun:ml_at_interrupt_context
-
-
+fun:ml_stack_remaining
+fun:ml_stack_base
+fun:ml_stack_size
diff --git a/san/kasan-blacklist-dynamic b/san/kasan-blacklist-dynamic
new file mode 100644 (file)
index 0000000..fea2f1c
--- /dev/null
@@ -0,0 +1,16 @@
+# entry = <kext>:<func>:<type>
+#
+# <type> = [ kfree zfree fsfree memr memw strr strw read write rw free mem str poison ]
+# See kasan_internal.h for descriptions of the types
+#
+# <kext> = last component of kext bundle ID. Use '__kernel__' for xnu proper.
+#
+# Any field can be empty, which matches everything
+
+
+# OSKext::copyInfo copies the whole cstrings section
+__kernel__:_ZN6OSKext8copyInfoEP7OSArray:memr
+
+# For unit-testing KASan
+__kernel__:test_blacklist:test
+__kernel__:test_blacklist_str:memr
index 9313e400310ed7957739bafe686317eeca215c8f..bd1704d3030521fff10330a9d88877cc970d2183 100644 (file)
@@ -21,9 +21,6 @@ src:./osfmk/i386/vmx/vmx_cpu.c
 src:./osfmk/kern/locks.c
 src:./osfmk/prng/random.c
 src:./osfmk/x86_64/loose_ends.c
-src:./osfmk/x86_64/xcpm/xcpm_dvfs.c
-src:./osfmk/x86_64/xcpm/xcpm_idle.c
-src:./osfmk/x86_64/xcpm/xcpm_ioctl.c
 src:./pexpert/gen/bootargs.c
 src:./pexpert/gen/device_tree.c
 src:./pexpert/gen/pe_gen.c
index 12869e512298d2ecf2c7cc0818e8037e31b6b57f..b023ded1c948529a759ea00ed8039671c119f505 100644 (file)
@@ -42,6 +42,7 @@
 #include <kasan_internal.h>
 
 int __asan_option_detect_stack_use_after_return = 0;
+int fakestack_enabled = 0;
 
 #define FAKESTACK_HEADER_SZ 64
 #define FAKESTACK_NUM_SZCLASS 7
@@ -69,28 +70,40 @@ static const unsigned long fakestack_min = 1 << 6;
 static const unsigned long __unused fakestack_max = 1 << 16;
 
 /*
- * Mark the current thread as being in a fakestack operation, to avoid reentrancy
- * issues. If set, disable fakestack allocation.
+ * Enter a fakestack critical section in a reentrant-safe fashion. Returns true on
+ * success with the kasan lock held.
  */
-static boolean_t
-thread_enter_fakestack(void)
+static bool
+thread_enter_fakestack(boolean_t *flags)
 {
-       thread_t thread = current_thread();
-       if (thread) {
-               return OSIncrementAtomic(&kasan_get_thread_data(current_thread())->in_fakestack);
-       } else {
-               return 0;
+       thread_t cur = current_thread();
+       if (cur && kasan_lock_held(cur)) {
+               /* current thread is already in kasan - fail */
+               return false;
        }
+       kasan_lock(flags);
+       return true;
 }
 
-static boolean_t
-thread_exit_fakestack(void)
+static volatile long suspend_count;
+static const long suspend_threshold = 20;
+
+void
+kasan_fakestack_suspend(void)
 {
-       thread_t thread = current_thread();
-       if (thread) {
-               return OSDecrementAtomic(&kasan_get_thread_data(current_thread())->in_fakestack);
-       } else {
-               return 0;
+       if (OSIncrementAtomicLong(&suspend_count) == suspend_threshold) {
+               __asan_option_detect_stack_use_after_return = 0;
+       }
+}
+
+void
+kasan_fakestack_resume(void)
+{
+       long orig = OSDecrementAtomicLong(&suspend_count);
+       assert(orig >= 0);
+
+       if (fakestack_enabled && orig == suspend_threshold) {
+               __asan_option_detect_stack_use_after_return = 1;
        }
 }
 
@@ -155,24 +168,21 @@ kasan_fakestack_alloc(int sz_class, size_t realsz)
                return 0;
        }
 
-       boolean_t flags;
        uptr ret = 0;
        size_t sz = fakestack_min << sz_class;
        assert(realsz <= sz);
        assert(sz <= fakestack_max);
        zone_t zone = fakestack_zones[sz_class];
 
-       if (thread_enter_fakestack()) {
+       boolean_t flags;
+       if (!thread_enter_fakestack(&flags)) {
                return 0;
        }
 
-       kasan_lock(&flags);
        kasan_fakestack_gc(current_thread()); /* XXX: optimal? */
 
        ret = (uptr)zget(zone);
 
-       thread_exit_fakestack();
-
        if (ret) {
                size_t leftrz = 32 + FAKESTACK_HEADER_SZ;
                size_t validsz = realsz - 32 - 16; /* remove redzones */
@@ -204,7 +214,6 @@ kasan_fakestack_free(int sz_class, uptr dst, size_t realsz)
        }
 
        assert(realsz <= (fakestack_min << sz_class));
-       assert(__asan_option_detect_stack_use_after_return);
 
        vm_size_t sz = fakestack_min << sz_class;
        zone_t zone = fakestack_zones[sz_class];
@@ -234,14 +243,10 @@ kasan_fakestack_free(int sz_class, uptr dst, size_t realsz)
 void NOINLINE
 kasan_unpoison_fakestack(thread_t thread)
 {
-       if (!__asan_option_detect_stack_use_after_return) {
-               return;
-       }
-
        boolean_t flags;
-       kasan_lock(&flags);
-
-       thread_enter_fakestack();
+       if (!thread_enter_fakestack(&flags)) {
+               panic("expected success entering fakestack\n");
+       }
 
        struct fakestack_header_list *head = &kasan_get_thread_data(thread)->fakestack_head;
        struct fakestack_header *cur;
@@ -252,7 +257,6 @@ kasan_unpoison_fakestack(thread_t thread)
        }
 
        kasan_fakestack_gc(thread);
-       thread_exit_fakestack();
        kasan_unlock(flags);
 }
 
@@ -283,7 +287,9 @@ kasan_init_fakestack(void)
        }
 
        /* globally enable */
-       __asan_option_detect_stack_use_after_return = 1;
+       if (fakestack_enabled) {
+               __asan_option_detect_stack_use_after_return = 1;
+       }
 }
 
 #else /* FAKESTACK */
@@ -318,7 +324,6 @@ kasan_fakestack_free(int __unused sz_class, uptr __unused dst, size_t __unused r
 
 void kasan_init_thread(struct kasan_thread_data *td)
 {
-       td->in_fakestack = 0;
        LIST_INIT(&td->fakestack_head);
 }
 
index c95207cf24f7bedd1ff429205fbf418eca4d36ce..2bbed97e37905385e06bf8723f9979fdf3847b86 100644 (file)
 #include <kasan_internal.h>
 #include <memintrinsics.h>
 
-#if MEMINTRINSICS
-static bool check_intrinsics = true;
-#else
-static bool check_intrinsics = false;
-#endif
-
 void
 __asan_bcopy(const void *src, void *dst, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(src, sz, TYPE_MEMLD);
-               kasan_check_range(dst, sz, TYPE_MEMSTR);
-       }
+       kasan_check_range(src, sz, TYPE_MEMR);
+       kasan_check_range(dst, sz, TYPE_MEMW);
        __nosan_bcopy(src, dst, sz);
 }
 
 void *
 __asan_memmove(void *src, const void *dst, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(src, sz, TYPE_MEMLD);
-               kasan_check_range(dst, sz, TYPE_MEMSTR);
-       }
+       kasan_check_range(src, sz, TYPE_MEMR);
+       kasan_check_range(dst, sz, TYPE_MEMW);
        return __nosan_memmove(src, dst, sz);
 }
 
 void *
 __asan_memcpy(void *dst, const void *src, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(src, sz, TYPE_MEMLD);
-               kasan_check_range(dst, sz, TYPE_MEMSTR);
-       }
+       kasan_check_range(src, sz, TYPE_MEMR);
+       kasan_check_range(dst, sz, TYPE_MEMW);
        return __nosan_memcpy(dst, src, sz);
 }
 
 void *
 __asan_memset(void *dst, int c, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(dst, sz, TYPE_MEMSTR);
-       }
+       kasan_check_range(dst, sz, TYPE_MEMW);
        return __nosan_memset(dst, c, sz);
 }
 
 void
 __asan_bzero(void *dst, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(dst, sz, TYPE_MEMSTR);
-       }
+       kasan_check_range(dst, sz, TYPE_MEMW);
        __nosan_bzero(dst, sz);
 }
 
 int
 __asan_bcmp(const void *a, const void *b, size_t len)
 {
-       if (check_intrinsics) {
-               kasan_check_range(a, len, TYPE_MEMLD);
-               kasan_check_range(b, len, TYPE_MEMLD);
-       }
+       kasan_check_range(a, len, TYPE_MEMR);
+       kasan_check_range(b, len, TYPE_MEMR);
        return __nosan_bcmp(a, b, len);
 }
 
 int
 __asan_memcmp(const void *a, const void *b, size_t n)
 {
-       if (check_intrinsics) {
-               kasan_check_range(a, n, TYPE_MEMLD);
-               kasan_check_range(b, n, TYPE_MEMLD);
-       }
+       kasan_check_range(a, n, TYPE_MEMR);
+       kasan_check_range(b, n, TYPE_MEMR);
        return __nosan_memcmp(a, b, n);
 }
 
 size_t
 __asan_strlcpy(char *dst, const char *src, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(dst, sz, TYPE_STRINGSTR);
-       }
+       kasan_check_range(dst, sz, TYPE_STRW);
        return __nosan_strlcpy(dst, src, sz);
 }
 
 size_t
 __asan_strlcat(char *dst, const char *src, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(dst, sz, TYPE_STRINGSTR);
-       }
+       kasan_check_range(dst, sz, TYPE_STRW);
        return __nosan_strlcat(dst, src, sz);
 }
 
 char *
 __asan_strncpy(char *dst, const char *src, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(dst, sz, TYPE_STRINGSTR);
-       }
+       kasan_check_range(dst, sz, TYPE_STRW);
        return __nosan_strncpy(dst, src, sz);
 }
 
 char *
 __asan_strncat(char *dst, const char *src, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(dst, strlen(dst) + sz + 1, TYPE_STRINGSTR);
-       }
+       kasan_check_range(dst, strlen(dst) + sz + 1, TYPE_STRW);
        return __nosan_strncat(dst, src, sz);
 }
 
 size_t
 __asan_strnlen(const char *src, size_t sz)
 {
-       if (check_intrinsics) {
-               kasan_check_range(src, sz, TYPE_STRINGLD);
-       }
-
+       kasan_check_range(src, sz, TYPE_STRR);
        return __nosan_strnlen(src, sz);
 }
 
@@ -160,8 +129,6 @@ size_t
 __asan_strlen(const char *src)
 {
        size_t sz = __nosan_strlen(src);
-       if (check_intrinsics) {
-               kasan_check_range(src, sz + 1, TYPE_STRINGLD);
-       }
+       kasan_check_range(src, sz + 1, TYPE_STRR);
        return sz;
 }
index 820af1b7f17441672d3ce20bb73ce106f6c844e4..6dc379c1a0b4d9b2f718cb26dc6bb191a350f970 100644 (file)
@@ -434,12 +434,14 @@ static int test_strncat(struct kasan_test *t)
 }
 
 /* we ignore the top *two* frames in backtrace - so add an extra one */
-static int NOINLINE test_blacklist_helper(void)
+static int __attribute__((noinline))
+test_blacklist_helper(void)
 {
        return kasan_is_blacklisted(TYPE_TEST);
 }
 
-static int NOINLINE test_blacklist(struct kasan_test *t)
+static int __attribute__((noinline))
+test_blacklist(struct kasan_test *t)
 {
        TEST_START(t);
        int res = (int)!test_blacklist_helper();
@@ -447,12 +449,13 @@ static int NOINLINE test_blacklist(struct kasan_test *t)
        return 0;
 }
 
-static int NOINLINE test_blacklist_str(struct kasan_test *t)
+static int __attribute__((noinline))
+test_blacklist_str(struct kasan_test *t)
 {
        TEST_START(t);
        char a1[8];
 
-       strlcpy(a1, "looooooooonnnnggg", 9);
+       bcopy("123456", a1, 8);
 
        TEST_DONE(t, 0); /* success */
        return 0;
@@ -557,7 +560,7 @@ kasan_run_test(struct kasan_test *test_list, int testno, int fail)
                /* Triggering a KASan violation will return here by longjmp, bypassing
                 * stack unpoisoning, so do it here explicitly. We just hope that
                 * fakestack free will happen later... */
-               kasan_unpoison_curstack();
+               kasan_unpoison_curstack(true);
 
                if (t->result) {
                        /* faulted, but at the wrong place */
index 93e8e416e6aadef7698e86096bae899199adbe0a..e2cb6d3bdd0beb85e1921a720a501498edd43436 100644 (file)
@@ -194,14 +194,12 @@ kasan_map_shadow_superpage_zero(vm_offset_t address, vm_size_t size)
 void
 kasan_map_shadow(vm_offset_t address, vm_size_t size, bool is_zero)
 {
-       size = vm_map_round_page(size, PAGE_MASK);
-       vm_size_t j;
-
-       for (j = 0; j < size; j += I386_PGBYTES) {
+       vm_offset_t shadow_base = vm_map_trunc_page(SHADOW_FOR_ADDRESS(address), PAGE_MASK);
+       vm_offset_t shadow_top = vm_map_round_page(SHADOW_FOR_ADDRESS(address + size), PAGE_MASK);
 
-               vm_offset_t virt_shadow_target = (vm_offset_t)SHADOW_FOR_ADDRESS(address + j);
+       for (; shadow_base < shadow_top; shadow_base += I386_PGBYTES) {
 
-               split_addr_t addr = split_address(virt_shadow_target);
+               split_addr_t addr = split_address(shadow_base);
                assert(addr.pml4 == 507 || addr.pml4 == 508);
 
                uint64_t *L3;
@@ -260,10 +258,10 @@ kasan_map_shadow(vm_offset_t address, vm_size_t size, bool is_zero)
                        L1[addr.pt] = newpte
                                | INTEL_PTE_VALID
                                | INTEL_PTE_NX;
-               }
 
-               /* adding a new entry, this is not strictly required */
-               invlpg(virt_shadow_target);
+                       /* adding a new entry, this is not strictly required */
+                       invlpg(shadow_base);
+               }
        }
 }
 
@@ -334,3 +332,42 @@ kasan_reserve_memory(void *_args)
        panic("KASAN: could not reserve memory");
 }
 
+bool
+kasan_is_shadow_mapped(uintptr_t shadowp)
+{
+       split_addr_t addr = split_address(shadowp);
+       assert(addr.pml4 == 507 || addr.pml4 == 508);
+
+       uint64_t *L3;
+       uint64_t *L2;
+       uint64_t *L1;
+
+       L3 = (uint64_t *)(IdlePML4[addr.pml4] & ~PAGE_MASK);
+       if (L3 == NULL) {
+               return false;
+       }
+       L3 = (uint64_t *)phys2virt(L3);
+
+       L2 = (uint64_t *)(L3[addr.pdpt] & ~PAGE_MASK);
+       if (L2 == NULL) {
+               return false;
+       }
+       L2 = (uint64_t *)phys2virt(L2);
+
+       uint64_t pde = L2[addr.pd];
+       if ((pde & (INTEL_PTE_VALID|INTEL_PTE_PS)) == (INTEL_PTE_VALID|INTEL_PTE_PS)) {
+               /* mapped as superpage */
+               return true;
+       }
+       L1 = (uint64_t *)(pde & ~PAGE_MASK);
+       if (L1 == NULL) {
+               return false;
+       }
+       L1 = (uint64_t *)phys2virt(L1);
+
+       if (L1[addr.pt] & INTEL_PTE_VALID) {
+               return true;
+       }
+
+       return false;
+}
index 1723fcef197e8f75f9301f8115b59c2e438b92e9..01faa38014c090cfc79c03e74026f98d94827215 100644 (file)
 #include <kasan_internal.h>
 #include <memintrinsics.h>
 
-#if !KASAN_DEBUG
-# undef NOINLINE
-# define NOINLINE
-#endif
-
 const uintptr_t __asan_shadow_memory_dynamic_address = KASAN_SHIFT;
 
-static long kexts_loaded;
-
-long shadow_pages_total;
-long shadow_pages_used;
+static unsigned kexts_loaded;
+unsigned shadow_pages_total;
+unsigned shadow_pages_used;
 
 vm_offset_t kernel_vbase;
 vm_offset_t kernel_vtop;
 
-static bool kasan_initialized;
-static int kasan_enabled;
-static int quarantine_enabled = 1;
+static unsigned kasan_enabled;
+static unsigned quarantine_enabled;
+static unsigned enabled_checks = TYPE_ALL; /* bitmask of enabled checks */
+static unsigned report_ignored;            /* issue non-fatal report for disabled/blacklisted checks */
+static unsigned free_yield = 0;            /* ms yield after each free */
+
+/* forward decls */
+static void kasan_crash_report(uptr p, uptr width, access_t access, violation_t reason);
+static void kasan_log_report(uptr p, uptr width, access_t access, violation_t reason);
 
-static void kasan_crash_report(uptr p, uptr width, unsigned access_type);
+/* imported osfmk functions */
 extern vm_offset_t ml_stack_base(void);
 extern vm_size_t ml_stack_size(void);
 
-#define ABI_UNSUPPORTED do { panic("KASan: unsupported ABI: %s\n", __func__); } while (0)
+/*
+ * unused: expected to be called, but (currently) does nothing
+ */
+#define UNUSED_ABI(func, ...) \
+       _Pragma("clang diagnostic push") \
+       _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
+       void func(__VA_ARGS__); \
+       void func(__VA_ARGS__) {}; \
+       _Pragma("clang diagnostic pop") \
 
-#define BACKTRACE_MAXFRAMES 16
+static const size_t BACKTRACE_BITS       = 4;
+static const size_t BACKTRACE_MAXFRAMES  = (1UL << BACKTRACE_BITS) - 1;
 
 decl_simple_lock_data(, kasan_vm_lock);
-
-_Atomic int unsafe_count = 0;
-
-void
-kasan_unsafe_start(void)
-{
-       if (__c11_atomic_fetch_add(&unsafe_count, 1, memory_order_relaxed) == 128) {
-               panic("kasan_unsafe_start overflow");
-       }
-}
-
-void
-kasan_unsafe_end(void)
-{
-       if (__c11_atomic_fetch_sub(&unsafe_count, 1, memory_order_relaxed) == 0) {
-               panic("kasan_unsafe_end underflow");
-       }
-}
-
-static bool
-kasan_in_unsafe(void)
-{
-       return atomic_load_explicit(&unsafe_count, memory_order_relaxed) != 0;
-}
+static thread_t kasan_lock_holder;
 
 /*
  * kasan is called from the interrupt path, so we need to disable interrupts to
@@ -117,15 +103,47 @@ kasan_lock(boolean_t *b)
 {
        *b = ml_set_interrupts_enabled(false);
        simple_lock(&kasan_vm_lock);
+       kasan_lock_holder = current_thread();
 }
 
 void
 kasan_unlock(boolean_t b)
 {
+       kasan_lock_holder = THREAD_NULL;
        simple_unlock(&kasan_vm_lock);
        ml_set_interrupts_enabled(b);
 }
 
+/* Return true if 'thread' holds the kasan lock. Only safe if 'thread' == current
+ * thread */
+bool
+kasan_lock_held(thread_t thread)
+{
+       return thread && thread == kasan_lock_holder;
+}
+
+static inline bool
+kasan_check_enabled(access_t access)
+{
+       return kasan_enabled && (enabled_checks & access) && !kasan_is_blacklisted(access);
+}
+
+static inline bool
+kasan_poison_active(uint8_t flags)
+{
+       switch (flags) {
+       case ASAN_GLOBAL_RZ:
+               return kasan_check_enabled(TYPE_POISON_GLOBAL);
+       case ASAN_HEAP_RZ:
+       case ASAN_HEAP_LEFT_RZ:
+       case ASAN_HEAP_RIGHT_RZ:
+       case ASAN_HEAP_FREED:
+               return kasan_check_enabled(TYPE_POISON_HEAP);
+       default:
+               return true;
+       };
+}
+
 /*
  * poison redzones in the shadow map
  */
@@ -144,7 +162,7 @@ kasan_poison(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t right
        assert((leftrz & 0x07) == 0);
        assert((total & 0x07) == 0);
 
-       if (!kasan_enabled || !kasan_initialized) {
+       if (!kasan_enabled || !kasan_poison_active(flags)) {
                return;
        }
 
@@ -170,7 +188,7 @@ kasan_poison(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t right
                shadow[i] = l_flags;
        }
        for (; i < leftrz + size; i++) {
-               shadow[i] = ASAN_VALID; /* not strictly necessary */
+               shadow[i] = ASAN_VALID; /* XXX: should not be necessary */
        }
        if (partial && (i < total)) {
                shadow[i] = partial;
@@ -179,8 +197,6 @@ kasan_poison(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t right
        for (; i < total; i++) {
                shadow[i] = r_flags;
        }
-
-       asm volatile("" ::: "memory"); /* compiler barrier XXX: is this needed? */
 }
 
 void
@@ -204,12 +220,19 @@ kasan_unpoison_stack(vm_offset_t base, vm_size_t size)
 {
        assert(base);
        assert(size);
+
+       /* align base and size to 8 bytes */
+       vm_offset_t align = base & 0x7;
+       base -= align;
+       size += align;
+       size = (size + 7) & ~0x7;
+
        kasan_unpoison((void *)base, size);
 }
 
 /*
  * write junk into the redzones
-*/
+ */
 static void NOINLINE
 kasan_rz_clobber(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t rightrz)
 {
@@ -241,30 +264,43 @@ kasan_rz_clobber(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t r
 #endif
 }
 
-void NOINLINE
-kasan_check_range(const void *x, size_t sz, unsigned access_type)
+/*
+ * Report a violation that may be disabled and/or blacklisted. This can only be
+ * called for dynamic checks (i.e. where the fault is recoverable). Use
+ * kasan_crash_report() for static (unrecoverable) violations.
+ *
+ * access: what we were trying to do when the violation occured
+ * reason: what failed about the access
+ */
+static void
+kasan_violation(uintptr_t addr, size_t size, access_t access, violation_t reason)
 {
-       vm_offset_t invalid;
-
-       if (kasan_in_unsafe()) {
+       assert(__builtin_popcount(access) == 1);
+       if (!kasan_check_enabled(access)) {
+               if (report_ignored) {
+                       kasan_log_report(addr, size, access, reason);
+               }
                return;
        }
+       kasan_crash_report(addr, size, access, reason);
+}
 
-       if (kasan_range_poisoned((vm_offset_t)x, sz, &invalid)) {
-               if (kasan_is_blacklisted(access_type)) {
-                       return;
-               }
-               kasan_crash_report(invalid, sz, access_type);
-               /* NOTREACHED */
+void NOINLINE
+kasan_check_range(const void *x, size_t sz, access_t access)
+{
+       uintptr_t invalid;
+       uintptr_t ptr = (uintptr_t)x;
+       if (kasan_range_poisoned(ptr, sz, &invalid)) {
+               size_t remaining = sz - (invalid - ptr);
+               kasan_violation(invalid, remaining, access, 0);
        }
 }
 
 /*
- * Check that [base, base+sz) has shadow value `shadow'
- * If not, report a KASan-violation on `addr'
+ * Return true if [base, base+sz) is unpoisoned or has given shadow value.
  */
-static void
-kasan_assert_shadow(vm_address_t base, vm_size_t sz, vm_address_t addr, uint8_t shadow)
+static bool
+kasan_check_shadow(vm_address_t base, vm_size_t sz, uint8_t shadow)
 {
        sz -= 8 - (base % 8);
        base += 8 - (base % 8);
@@ -273,11 +309,12 @@ kasan_assert_shadow(vm_address_t base, vm_size_t sz, vm_address_t addr, uint8_t
 
        while (base < end) {
                uint8_t *sh = SHADOW_FOR_ADDRESS(base);
-               if (*sh != shadow) {
-                       __asan_report_load1(addr);
+               if (*sh && *sh != shadow) {
+                       return false;
                }
                base += 8;
        }
+       return true;
 }
 
 /*
@@ -287,16 +324,16 @@ kasan_assert_shadow(vm_address_t base, vm_size_t sz, vm_address_t addr, uint8_t
  */
 
 static const char *
-access_type_str(unsigned type)
+access_str(access_t type)
 {
-       if (type & TYPE_LOAD_ALL) {
-               return "load";
-       } else if (type & TYPE_STORE_ALL) {
-               return "store";
+       if (type & TYPE_READ) {
+               return "load from";
+       } else if (type & TYPE_WRITE) {
+               return "store to";
        } else if (type & TYPE_FREE) {
-               return "free";
+               return "free of";
        } else {
-               return "access";
+               return "access of";
        }
 }
 
@@ -328,43 +365,59 @@ static size_t
 kasan_shadow_crashlog(uptr p, char *buf, size_t len)
 {
        int i,j;
-       size_t l = 0;
+       size_t n = 0;
        int before = CRASH_CONTEXT_BEFORE;
        int after = CRASH_CONTEXT_AFTER;
 
        uptr shadow = (uptr)SHADOW_FOR_ADDRESS(p);
        uptr shadow_p = shadow;
+       uptr shadow_page = vm_map_round_page(shadow_p, PAGE_MASK);
 
        /* rewind to start of context block */
        shadow &= ~((uptr)0xf);
        shadow -= 16 * before;
 
+       n += snprintf(buf+n, len-n,
+                       " Shadow             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
+
        for (i = 0; i < 1 + before + after; i++, shadow += 16) {
-               if (vm_map_round_page(shadow, PAGE_MASK) != vm_map_round_page(shadow_p, PAGE_MASK)) {
-                       /* don't cross a page boundary, in case the shadow is unmapped */
-                       /* XXX: ideally we check instead of ignore */
+               if ((vm_map_round_page(shadow, PAGE_MASK) != shadow_page) && !kasan_is_shadow_mapped(shadow)) {
+                       /* avoid unmapped shadow when crossing page boundaries */
                        continue;
                }
 
-               l += snprintf(buf+l, len-l, " %#16lx: ", shadow);
+               n += snprintf(buf+n, len-n, " %16lx:", shadow);
+
+               char *left = " ";
+               char *right;
 
                for (j = 0; j < 16; j++) {
                        uint8_t *x = (uint8_t *)(shadow + j);
-                       l += snprintf(buf+l, len-l, "%02x ", (unsigned)*x);
+
+                       right = " ";
+                       if ((uptr)x == shadow_p) {
+                               left = "[";
+                               right = "]";
+                       } else if ((uptr)(x + 1) == shadow_p) {
+                               right = "";
+                       }
+
+                       n += snprintf(buf+n, len-n, "%s%02x%s", left, (unsigned)*x, right);
+                       left = "";
                }
-               l += snprintf(buf+l, len-l, "\n");
+               n += snprintf(buf+n, len-n, "\n");
        }
 
-       l += snprintf(buf+l, len-l, "\n");
-       return l;
+       n += snprintf(buf+n, len-n, "\n");
+       return n;
 }
 
-static void NOINLINE
-kasan_crash_report(uptr p, uptr width, unsigned access_type)
+static void
+kasan_report_internal(uptr p, uptr width, access_t access, violation_t reason, bool dopanic)
 {
        const size_t len = 4096;
        static char buf[len];
-       size_t l = 0;
+       size_t n = 0;
 
        uint8_t *shadow_ptr = SHADOW_FOR_ADDRESS(p);
        uint8_t shadow_type = *shadow_ptr;
@@ -372,28 +425,66 @@ kasan_crash_report(uptr p, uptr width, unsigned access_type)
        if (!shadow_str) {
                shadow_str = "<invalid>";
        }
+       buf[0] = '\0';
+
+       if (reason == REASON_MOD_OOB || reason == REASON_BAD_METADATA) {
+               n += snprintf(buf+n, len-n, "KASan: free of corrupted/invalid object %#lx\n", p);
+       } else if (reason == REASON_MOD_AFTER_FREE) {
+               n += snprintf(buf+n, len-n, "KASan: UaF of quarantined object %#lx\n", p);
+       } else {
+               n += snprintf(buf+n, len-n, "KASan: invalid %lu-byte %s %#lx [%s]\n",
+                               width, access_str(access), p, shadow_str);
+       }
+       n += kasan_shadow_crashlog(p, buf+n, len-n);
 
+       if (dopanic) {
+               panic("%s", buf);
+       } else {
+               printf("%s", buf);
+       }
+}
+
+static void NOINLINE OS_NORETURN
+kasan_crash_report(uptr p, uptr width, access_t access, violation_t reason)
+{
        kasan_handle_test();
+       kasan_report_internal(p, width, access, reason, true);
+       __builtin_unreachable(); /* we cant handle this returning anyway */
+}
 
-       buf[0] = '\0';
-       l += snprintf(buf+l, len-l,
-                       "KASan: invalid %lu-byte %s @ %#lx [%s]\n"
-                       "Shadow %#02x @ %#lx\n\n",
-                       width, access_type_str(access_type), p, shadow_str,
-                       (unsigned)shadow_type, (unsigned long)shadow_ptr);
+static void
+kasan_log_report(uptr p, uptr width, access_t access, violation_t reason)
+{
+       const size_t len = 256;
+       char buf[len];
+       size_t l = 0;
+       uint32_t nframes = 14;
+       uintptr_t frames[nframes];
+       uintptr_t *bt = frames;
+
+       kasan_report_internal(p, width, access, reason, false);
+
+       /*
+        * print a backtrace
+        */
 
-       l += kasan_shadow_crashlog(p, buf+l, len-l);
+       nframes = backtrace_frame(bt, nframes, __builtin_frame_address(0)); /* ignore current frame */
 
-       panic("%s", buf);
+       buf[0] = '\0';
+       l += snprintf(buf+l, len-l, "Backtrace: ");
+       for (uint32_t i = 0; i < nframes; i++) {
+               l += snprintf(buf+l, len-l, "%lx,", VM_KERNEL_UNSLIDE(bt[i]));
+       }
+       l += snprintf(buf+l, len-l, "\n");
+
+       printf("%s", buf);
 }
 
 #define REPORT_DECLARE(n) \
-       void __asan_report_load##n(uptr p)  { kasan_crash_report(p, n, TYPE_LOAD); } \
-       void __asan_report_store##n(uptr p) { kasan_crash_report(p, n, TYPE_STORE); } \
-       void __asan_report_exp_load##n(uptr, int32_t); \
-       void __asan_report_exp_store##n(uptr, int32_t); \
-       void __asan_report_exp_load##n(uptr __unused p, int32_t __unused e) { ABI_UNSUPPORTED; } \
-       void __asan_report_exp_store##n(uptr __unused p, int32_t __unused e) { ABI_UNSUPPORTED; }
+       void OS_NORETURN __asan_report_load##n(uptr p)  { kasan_crash_report(p, n, TYPE_LOAD,  0); } \
+       void OS_NORETURN __asan_report_store##n(uptr p) { kasan_crash_report(p, n, TYPE_STORE, 0); } \
+       void UNSUPPORTED_API(__asan_report_exp_load##n, uptr a, int32_t b); \
+       void UNSUPPORTED_API(__asan_report_exp_store##n, uptr a, int32_t b);
 
 REPORT_DECLARE(1)
 REPORT_DECLARE(2)
@@ -401,21 +492,32 @@ REPORT_DECLARE(4)
 REPORT_DECLARE(8)
 REPORT_DECLARE(16)
 
-void __asan_report_load_n(uptr p, unsigned long sz)  { kasan_crash_report(p, sz, TYPE_LOAD); }
-void __asan_report_store_n(uptr p, unsigned long sz) { kasan_crash_report(p, sz, TYPE_STORE); }
+void OS_NORETURN __asan_report_load_n(uptr p, unsigned long sz)  { kasan_crash_report(p, sz, TYPE_LOAD,  0); }
+void OS_NORETURN __asan_report_store_n(uptr p, unsigned long sz) { kasan_crash_report(p, sz, TYPE_STORE, 0); }
 
 /* unpoison the current stack */
-/* XXX: as an optimization, we could unpoison only up to the current stack depth */
 void NOINLINE
-kasan_unpoison_curstack(void)
+kasan_unpoison_curstack(bool whole_stack)
 {
-       kasan_unpoison_stack(ml_stack_base(), ml_stack_size());
+       uintptr_t base = ml_stack_base();
+       size_t sz = ml_stack_size();
+       uintptr_t cur = (uintptr_t)&base;
+
+       if (whole_stack) {
+               cur = base;
+       }
+
+       if (cur >= base && cur < base + sz) {
+               /* unpoison from current stack depth to the top */
+               size_t unused = cur - base;
+               kasan_unpoison_stack(cur, sz - unused);
+       }
 }
 
 void NOINLINE
 __asan_handle_no_return(void)
 {
-       kasan_unpoison_curstack();
+       kasan_unpoison_curstack(false);
        kasan_unpoison_fakestack(current_thread());
 }
 
@@ -425,7 +527,7 @@ kasan_range_poisoned(vm_offset_t base, vm_size_t size, vm_offset_t *first_invali
        uint8_t *shadow;
        vm_size_t i;
 
-       if (!kasan_initialized || !kasan_enabled) {
+       if (!kasan_enabled) {
                return false;
        }
 
@@ -474,16 +576,16 @@ kasan_load_kext(vm_offset_t base, vm_size_t __unused size, const void *bundleid)
        unsigned long sectsz;
        void *sect;
 
+#if KASAN_DYNAMIC_BLACKLIST
+       kasan_dybl_load_kext(base, bundleid);
+#endif
+
        /* find the kasan globals segment/section */
        sect = getsectdatafromheader((void *)base, KASAN_GLOBAL_SEGNAME, KASAN_GLOBAL_SECTNAME, &sectsz);
        if (sect) {
                kasan_init_globals((vm_address_t)sect, (vm_size_t)sectsz);
                kexts_loaded++;
        }
-
-#if KASAN_DYNAMIC_BLACKLIST
-       kasan_dybl_load_kext(base, bundleid);
-#endif
 }
 
 void NOINLINE
@@ -504,11 +606,18 @@ kasan_unload_kext(vm_offset_t base, vm_size_t size)
 #endif
 }
 
+/*
+ * Turn off as much as possible for panic path etc. There's no way to turn it back
+ * on.
+ */
 void NOINLINE
 kasan_disable(void)
 {
        __asan_option_detect_stack_use_after_return = 0;
+       fakestack_enabled = 0;
        kasan_enabled = 0;
+       quarantine_enabled = 0;
+       enabled_checks = 0;
 }
 
 static void NOINLINE
@@ -522,21 +631,21 @@ kasan_init_xnu_globals(void)
        kernel_mach_header_t *header = (kernel_mach_header_t *)&_mh_execute_header;
 
        if (!header) {
-               printf("KASAN: failed to find kernel mach header\n");
-               printf("KASAN: redzones for globals not poisoned\n");
+               printf("KASan: failed to find kernel mach header\n");
+               printf("KASan: redzones for globals not poisoned\n");
                return;
        }
 
        globals = (vm_offset_t)getsectdatafromheader(header, seg, sect, &_size);
        if (!globals) {
-               printf("KASAN: failed to find segment %s section %s\n", seg, sect);
-               printf("KASAN: redzones for globals not poisoned\n");
+               printf("KASan: failed to find segment %s section %s\n", seg, sect);
+               printf("KASan: redzones for globals not poisoned\n");
                return;
        }
        size = (vm_size_t)_size;
 
-       printf("KASAN: found (%s,%s) at %#lx + %lu\n", seg, sect, globals, size);
-       printf("KASAN: poisoning redzone for %lu globals\n", size / sizeof(struct asan_global));
+       printf("KASan: found (%s,%s) at %#lx + %lu\n", seg, sect, globals, size);
+       printf("KASan: poisoning redzone for %lu globals\n", size / sizeof(struct asan_global));
 
        kasan_init_globals(globals, size);
 }
@@ -544,12 +653,12 @@ kasan_init_xnu_globals(void)
 void NOINLINE
 kasan_late_init(void)
 {
-       kasan_init_fakestack();
-       kasan_init_xnu_globals();
-
 #if KASAN_DYNAMIC_BLACKLIST
        kasan_init_dybl();
 #endif
+
+       kasan_init_fakestack();
+       kasan_init_xnu_globals();
 }
 
 void NOINLINE
@@ -584,6 +693,8 @@ kasan_debug_touch_mappings(vm_offset_t base, vm_size_t sz)
 void NOINLINE
 kasan_init(void)
 {
+       unsigned arg;
+
        simple_lock_init(&kasan_vm_lock, 0);
 
        /* Map all of the kernel text and data */
@@ -591,7 +702,39 @@ kasan_init(void)
 
        kasan_arch_init();
 
-       kasan_initialized = 1;
+       /*
+        * handle KASan boot-args
+        */
+
+       if (PE_parse_boot_argn("kasan.checks", &arg, sizeof(arg))) {
+               enabled_checks = arg;
+       }
+
+       if (PE_parse_boot_argn("kasan", &arg, sizeof(arg))) {
+               if (arg & KASAN_ARGS_FAKESTACK) {
+                       fakestack_enabled = 1;
+               }
+               if (arg & KASAN_ARGS_REPORTIGNORED) {
+                       report_ignored = 1;
+               }
+               if (arg & KASAN_ARGS_NODYCHECKS) {
+                       enabled_checks &= ~TYPE_DYNAMIC;
+               }
+               if (arg & KASAN_ARGS_NOPOISON_HEAP) {
+                       enabled_checks &= ~TYPE_POISON_HEAP;
+               }
+               if (arg & KASAN_ARGS_NOPOISON_GLOBAL) {
+                       enabled_checks &= ~TYPE_POISON_GLOBAL;
+               }
+       }
+
+       if (PE_parse_boot_argn("kasan.free_yield_ms", &arg, sizeof(arg))) {
+               free_yield = arg;
+       }
+
+       /* kasan.bl boot-arg handled in kasan_init_dybl() */
+
+       quarantine_enabled = 1;
        kasan_enabled = 1;
 }
 
@@ -600,7 +743,7 @@ kasan_notify_address_internal(vm_offset_t address, vm_size_t size, bool is_zero)
 {
        assert(address < VM_MAX_KERNEL_ADDRESS);
 
-       if (!kasan_initialized || !kasan_enabled) {
+       if (!kasan_enabled) {
                return;
        }
 
@@ -643,12 +786,13 @@ kasan_notify_address_nopoison(vm_offset_t address, vm_size_t size)
  */
 
 struct kasan_alloc_header {
-       uint32_t magic;
+       uint16_t magic;
+       uint16_t crc;
        uint32_t alloc_size;
        uint32_t user_size;
        struct {
-               uint32_t left_rz : 28;
-               uint32_t frames  : 4;
+               uint32_t left_rz : 32 - BACKTRACE_BITS;
+               uint32_t frames  : BACKTRACE_BITS;
        };
 };
 _Static_assert(sizeof(struct kasan_alloc_header) <= KASAN_GUARD_SIZE, "kasan alloc header exceeds guard size");
@@ -658,11 +802,18 @@ struct kasan_alloc_footer {
 };
 _Static_assert(sizeof(struct kasan_alloc_footer) <= KASAN_GUARD_SIZE, "kasan alloc footer exceeds guard size");
 
-#define MAGIC_XOR ((uint32_t)0xA110C8ED)
-static uint32_t
-magic_for_addr(vm_offset_t addr)
+#define LIVE_XOR ((uint16_t)0x3a65)
+#define FREE_XOR ((uint16_t)0xf233)
+
+static uint16_t
+magic_for_addr(vm_offset_t addr, uint16_t magic_xor)
 {
-       return (uint32_t)addr ^ MAGIC_XOR;
+       uint16_t magic = addr & 0xFFFF;
+       magic ^= (addr >> 16) & 0xFFFF;
+       magic ^= (addr >> 32) & 0xFFFF;
+       magic ^= (addr >> 48) & 0xFFFF;
+       magic ^= magic_xor;
+       return magic;
 }
 
 static struct kasan_alloc_header *
@@ -731,6 +882,25 @@ kasan_alloc_bt(uint32_t *ptr, vm_size_t sz, vm_size_t skip)
        return frames;
 }
 
+/* addr: user address of allocation */
+static uint16_t
+kasan_alloc_crc(vm_offset_t addr)
+{
+       struct kasan_alloc_header *h = header_for_user_addr(addr);
+       vm_size_t rightrz = h->alloc_size - h->user_size - h->left_rz;
+
+       uint16_t crc_orig = h->crc;
+       h->crc = 0;
+
+       uint16_t crc = 0;
+       crc = __nosan_crc16(crc, (void *)(addr - h->left_rz), h->left_rz);
+       crc = __nosan_crc16(crc, (void *)(addr + h->user_size), rightrz);
+
+       h->crc = crc_orig;
+
+       return crc;
+}
+
 /*
  * addr: base address of full allocation (including redzones)
  * size: total size of allocation (include redzones)
@@ -757,7 +927,7 @@ kasan_alloc(vm_offset_t addr, vm_size_t size, vm_size_t req, vm_size_t leftrz)
 
        /* stash the allocation sizes in the left redzone */
        struct kasan_alloc_header *h = header_for_user_addr(addr);
-       h->magic = magic_for_addr(addr);
+       h->magic = magic_for_addr(addr, LIVE_XOR);
        h->left_rz = leftrz;
        h->alloc_size = size;
        h->user_size = req;
@@ -767,6 +937,9 @@ kasan_alloc(vm_offset_t addr, vm_size_t size, vm_size_t req, vm_size_t leftrz)
        struct kasan_alloc_footer *f = footer_for_user_addr(addr, &fsize);
        h->frames = kasan_alloc_bt(f->backtrace, fsize, 2);
 
+       /* checksum the whole object, minus the user part */
+       h->crc = kasan_alloc_crc(addr);
+
        return addr;
 }
 
@@ -780,10 +953,6 @@ kasan_dealloc(vm_offset_t addr, vm_size_t *size)
 {
        assert(size && addr);
        struct kasan_alloc_header *h = header_for_user_addr(addr);
-       if (h->magic != magic_for_addr(addr)) {
-               /* no point blacklisting here - this is fatal */
-               kasan_crash_report(addr, *size, TYPE_FREE);
-       }
        *size = h->alloc_size;
        return addr - h->left_rz;
 }
@@ -796,7 +965,7 @@ vm_size_t
 kasan_user_size(vm_offset_t addr)
 {
        struct kasan_alloc_header *h = header_for_user_addr(addr);
-       assert(h->magic == magic_for_addr(addr));
+       assert(h->magic == magic_for_addr(addr, LIVE_XOR));
        return h->user_size;
 }
 
@@ -809,36 +978,30 @@ kasan_check_free(vm_offset_t addr, vm_size_t size, unsigned heap_type)
        struct kasan_alloc_header *h = header_for_user_addr(addr);
 
        /* map heap type to an internal access type */
-       unsigned type;
-       if (heap_type == KASAN_HEAP_KALLOC) {
-               type = TYPE_KFREE;
-       } else if (heap_type == KASAN_HEAP_ZALLOC) {
-               type = TYPE_ZFREE;
-       } else if (heap_type == KASAN_HEAP_FAKESTACK) {
-               type = TYPE_FSFREE;
-       }
+       access_t type = heap_type == KASAN_HEAP_KALLOC    ? TYPE_KFREE  :
+                       heap_type == KASAN_HEAP_ZALLOC    ? TYPE_ZFREE  :
+                       heap_type == KASAN_HEAP_FAKESTACK ? TYPE_FSFREE : 0;
 
-       /* check the magic matches */
-       if (h->magic != magic_for_addr(addr)) {
-               if (kasan_is_blacklisted(type)) {
-                       return;
-               }
-               kasan_crash_report(addr, size, type);
+       /* check the magic and crc match */
+       if (h->magic != magic_for_addr(addr, LIVE_XOR)) {
+               kasan_violation(addr, size, type, REASON_BAD_METADATA);
+       }
+       if (h->crc != kasan_alloc_crc(addr)) {
+               kasan_violation(addr, size, type, REASON_MOD_OOB);
        }
 
        /* check the freed size matches what we recorded at alloc time */
        if (h->user_size != size) {
-               if (kasan_is_blacklisted(type)) {
-                       return;
-               }
-               kasan_crash_report(addr, size, type);
+               kasan_violation(addr, size, type, REASON_INVALID_SIZE);
        }
 
        vm_size_t rightrz_sz = h->alloc_size - h->left_rz - h->user_size;
 
        /* Check that the redzones are valid */
-       kasan_assert_shadow(addr - h->left_rz, h->left_rz, addr, ASAN_HEAP_LEFT_RZ);
-       kasan_assert_shadow(addr + h->user_size, rightrz_sz, addr, ASAN_HEAP_RIGHT_RZ);
+       if (!kasan_check_shadow(addr - h->left_rz, h->left_rz, ASAN_HEAP_LEFT_RZ) ||
+               !kasan_check_shadow(addr + h->user_size, rightrz_sz, ASAN_HEAP_RIGHT_RZ)) {
+               kasan_violation(addr, size, type, REASON_BAD_METADATA);
+       }
 
        /* Check the allocated range is not poisoned */
        kasan_check_range((void *)addr, size, type);
@@ -851,15 +1014,15 @@ kasan_check_free(vm_offset_t addr, vm_size_t size, unsigned heap_type)
  */
 
 struct freelist_entry {
-       uint32_t magic;
-       uint32_t checksum;
+       uint16_t magic;
+       uint16_t crc;
        STAILQ_ENTRY(freelist_entry) list;
        union {
                struct {
                        vm_size_t size      : 28;
                        vm_size_t user_size : 28;
-                       vm_size_t frames    : 4; /* number of frames in backtrace */
-                       vm_size_t __unused  : 4;
+                       vm_size_t frames    : BACKTRACE_BITS; /* number of frames in backtrace */
+                       vm_size_t __unused  : 8 - BACKTRACE_BITS;
                };
                uint64_t bits;
        };
@@ -868,13 +1031,6 @@ struct freelist_entry {
 };
 _Static_assert(sizeof(struct freelist_entry) <= KASAN_GUARD_PAD, "kasan freelist header exceeds padded size");
 
-#define FREELIST_MAGIC_XOR ((uint32_t)0xF23333D)
-static uint32_t
-freelist_magic(vm_offset_t addr)
-{
-       return (uint32_t)addr ^ FREELIST_MAGIC_XOR;
-}
-
 struct quarantine {
        STAILQ_HEAD(freelist_head, freelist_entry) freelist;
        unsigned long entries;
@@ -889,6 +1045,12 @@ struct quarantine quarantines[] = {
        { STAILQ_HEAD_INITIALIZER((quarantines[KASAN_HEAP_FAKESTACK].freelist)), 0, QUARANTINE_ENTRIES, 0, QUARANTINE_MAXSIZE }
 };
 
+static uint16_t
+fle_crc(struct freelist_entry *fle)
+{
+       return __nosan_crc16(0, &fle->bits, fle->size - offsetof(struct freelist_entry, bits));
+}
+
 /*
  * addr, sizep: pointer/size of full allocation including redzone
  */
@@ -927,7 +1089,7 @@ kasan_free_internal(void **addrp, vm_size_t *sizep, int type,
 
        /* create a new freelist entry */
        fle = (struct freelist_entry *)addr;
-       fle->magic = freelist_magic((vm_offset_t)fle);
+       fle->magic = magic_for_addr((vm_offset_t)fle, FREE_XOR);
        fle->size = size;
        fle->user_size = user_size;
        fle->frames = 0;
@@ -936,7 +1098,9 @@ kasan_free_internal(void **addrp, vm_size_t *sizep, int type,
                fle->zone = *zone;
        }
        if (type != KASAN_HEAP_FAKESTACK) {
+               /* don't do expensive things on the fakestack path */
                fle->frames = kasan_alloc_bt(fle->backtrace, fle->size - sizeof(struct freelist_entry), 3);
+               fle->crc = fle_crc(fle);
        }
 
        boolean_t flg;
@@ -976,12 +1140,17 @@ kasan_free_internal(void **addrp, vm_size_t *sizep, int type,
 
                size = tofree->size;
                addr = (vm_offset_t)tofree;
-               if (tofree->magic != freelist_magic(addr)) {
-                       kasan_crash_report(addr, size, TYPE_FREE);
+
+               /* check the magic and crc match */
+               if (tofree->magic != magic_for_addr(addr, FREE_XOR)) {
+                       kasan_violation(addr, size, TYPE_UAF, REASON_MOD_AFTER_FREE);
+               }
+               if (type != KASAN_HEAP_FAKESTACK && tofree->crc != fle_crc(tofree)) {
+                       kasan_violation(addr, size, TYPE_UAF, REASON_MOD_AFTER_FREE);
                }
 
                /* clobber the quarantine header */
-               kasan_rz_clobber(addr, 0, sizeof(struct freelist_entry), 0);
+               __nosan_bzero((void *)addr, sizeof(struct freelist_entry));
 
        } else {
                /* quarantine is not full - don't really free anything */
@@ -1006,6 +1175,10 @@ kasan_free(void **addrp, vm_size_t *sizep, int type, zone_t *zone,
            vm_size_t user_size, bool quarantine)
 {
        kasan_free_internal(addrp, sizep, type, zone, user_size, 0, quarantine);
+
+       if (free_yield) {
+               thread_yield_internal(free_yield);
+       }
 }
 
 uptr
@@ -1028,12 +1201,11 @@ __asan_poison_cxx_array_cookie(uptr p)
        *shadow = ASAN_ARRAY_COOKIE;
 }
 
-#define ACCESS_CHECK_DECLARE(type, sz, access_type) \
+#define ACCESS_CHECK_DECLARE(type, sz, access) \
        void __asan_##type##sz(uptr addr) { \
-               kasan_check_range((const void *)addr, sz, access_type); \
+               kasan_check_range((const void *)addr, sz, access); \
        } \
-       void __asan_exp_##type##sz(uptr, int32_t); \
-       void __asan_exp_##type##sz(uptr __unused addr, int32_t __unused e) { ABI_UNSUPPORTED; }
+       void UNSUPPORTED_API(__asan_exp_##type##sz, uptr a, int32_t b);
 
 ACCESS_CHECK_DECLARE(load,  1,  TYPE_LOAD);
 ACCESS_CHECK_DECLARE(load,  2,  TYPE_LOAD);
@@ -1058,16 +1230,6 @@ __asan_storeN(uptr addr, size_t sz)
        kasan_check_range((const void *)addr, sz, TYPE_STORE);
 }
 
-void __asan_exp_loadN(uptr, size_t, int32_t);
-void __asan_exp_storeN(uptr, size_t, int32_t);
-void __asan_exp_loadN(uptr __unused addr, size_t __unused sz, int32_t __unused e) { ABI_UNSUPPORTED; }
-void __asan_exp_storeN(uptr __unused addr, size_t __unused sz, int32_t __unused e) { ABI_UNSUPPORTED; }
-
-void __asan_report_exp_load_n(uptr, unsigned long, int32_t);
-void __asan_report_exp_store_n(uptr, unsigned long, int32_t);
-void __asan_report_exp_load_n(uptr __unused p, unsigned long __unused sz, int32_t __unused e) { ABI_UNSUPPORTED; }
-void __asan_report_exp_store_n(uptr __unused p, unsigned long __unused sz, int32_t __unused e) { ABI_UNSUPPORTED; }
-
 static void
 kasan_set_shadow(uptr addr, size_t sz, uint8_t val)
 {
@@ -1086,115 +1248,76 @@ SET_SHADOW_DECLARE(f3)
 SET_SHADOW_DECLARE(f5)
 SET_SHADOW_DECLARE(f8)
 
+
 /*
- * XXX: implement these
+ * Call 'cb' for each contiguous range of the shadow map. This could be more
+ * efficient by walking the page table directly.
  */
-
-void __asan_alloca_poison(uptr addr, uptr size)
-{
-       (void)addr;
-       (void)size;
-}
-
-void __asan_allocas_unpoison(uptr top, uptr bottom)
+int
+kasan_traverse_mappings(pmap_traverse_callback cb, void *ctx)
 {
-       (void)top;
-       (void)bottom;
-}
-
-void
-__sanitizer_ptr_sub(uptr a, uptr b)
-{
-       (void)a;
-       (void)b;
-}
-
-void
-__sanitizer_ptr_cmp(uptr a, uptr b)
-{
-       (void)a;
-       (void)b;
-}
-
-void
-__asan_poison_stack_memory(uptr addr, size_t size)
-{
-       (void)addr;
-       (void)size;
-}
+       uintptr_t shadow_base = (uintptr_t)SHADOW_FOR_ADDRESS(VM_MIN_KERNEL_AND_KEXT_ADDRESS);
+       uintptr_t shadow_top = (uintptr_t)SHADOW_FOR_ADDRESS(VM_MAX_KERNEL_ADDRESS);
+       shadow_base = vm_map_trunc_page(shadow_base, PAGE_MASK);
+       shadow_top = vm_map_round_page(shadow_top, PAGE_MASK);
+
+       uintptr_t start = 0, end = 0;
+
+       for (uintptr_t addr = shadow_base; addr < shadow_top; addr += PAGE_SIZE) {
+               if (kasan_is_shadow_mapped(addr)) {
+                       if (start == 0) {
+                               start = addr;
+                       }
+                       end = addr + PAGE_SIZE;
+               } else if (start && end) {
+                       cb(start, end, ctx);
+                       start = end = 0;
+               }
+       }
 
-void
-__asan_unpoison_stack_memory(uptr addr, size_t size)
-{
-       (void)addr;
-       (void)size;
-}
+       if (start && end) {
+               cb(start, end, ctx);
+       }
 
-void
-__sanitizer_annotate_contiguous_container(const void *beg,
-               const void *end,
-               const void *old_mid,
-               const void *new_mid)
-{
-       (void)beg;
-       (void)end;
-       (void)old_mid;
-       (void)new_mid;
+       return 0;
 }
 
 /*
+ * XXX: implement these
  */
 
-void
-__asan_init(void)
-{
-}
-
-#define VERSION_DECLARE(v) \
-       void __asan_version_mismatch_check_##v(void); \
-       void __asan_version_mismatch_check_##v(void) {}
-
-VERSION_DECLARE(v8)
-VERSION_DECLARE(apple_802)
-VERSION_DECLARE(apple_900)
-
-void
-__asan_register_globals(uptr __unused a, uptr __unused b)
-{
-       ABI_UNSUPPORTED;
-}
-
-void
-__asan_unregister_globals(uptr __unused a, uptr __unused b)
-{
-       ABI_UNSUPPORTED;
-}
-
-void
-__asan_register_image_globals(uptr __unused ptr)
-{
-}
-
-void
-__asan_unregister_image_globals(uptr __unused ptr)
-{
-}
-
-void
-__asan_init_v5(void)
-{
-}
-
-void
-__asan_before_dynamic_init(uptr __unused arg)
-{
-}
+UNUSED_ABI(__asan_alloca_poison, uptr addr, uptr size);
+UNUSED_ABI(__asan_allocas_unpoison, uptr top, uptr bottom);
+UNUSED_ABI(__sanitizer_ptr_sub, uptr a, uptr b);
+UNUSED_ABI(__sanitizer_ptr_cmp, uptr a, uptr b);
+UNUSED_ABI(__sanitizer_annotate_contiguous_container, const void *a, const void *b, const void *c, const void *d);
+UNUSED_ABI(__asan_poison_stack_memory, uptr addr, size_t size);
+UNUSED_ABI(__asan_unpoison_stack_memory, uptr a, uptr b);
 
-void
-__asan_after_dynamic_init(void)
-{
-}
+/*
+ * Miscellaneous unimplemented asan ABI
+ */
 
+UNUSED_ABI(__asan_init, void);
+UNUSED_ABI(__asan_register_image_globals, uptr a);
+UNUSED_ABI(__asan_unregister_image_globals, uptr a);
+UNUSED_ABI(__asan_before_dynamic_init, uptr a);
+UNUSED_ABI(__asan_after_dynamic_init, void);
+UNUSED_ABI(__asan_version_mismatch_check_v8, void);
+UNUSED_ABI(__asan_version_mismatch_check_apple_802, void);
+UNUSED_ABI(__asan_version_mismatch_check_apple_900, void);
+UNUSED_ABI(__asan_version_mismatch_check_apple_902, void);
+
+void UNSUPPORTED_API(__asan_init_v5, void);
+void UNSUPPORTED_API(__asan_register_globals, uptr a, uptr b);
+void UNSUPPORTED_API(__asan_unregister_globals, uptr a, uptr b);
+void UNSUPPORTED_API(__asan_register_elf_globals, uptr a, uptr b, uptr c);
+void UNSUPPORTED_API(__asan_unregister_elf_globals, uptr a, uptr b, uptr c);
+
+void UNSUPPORTED_API(__asan_exp_loadN, uptr addr, size_t sz, int32_t e);
+void UNSUPPORTED_API(__asan_exp_storeN, uptr addr, size_t sz, int32_t e);
+void UNSUPPORTED_API(__asan_report_exp_load_n, uptr addr, unsigned long b, int32_t c);
+void UNSUPPORTED_API(__asan_report_exp_store_n, uptr addr, unsigned long b, int32_t c);
 
 /*
  *
@@ -1217,22 +1340,40 @@ sysctl_kasan_test(__unused struct sysctl_oid *oidp, __unused void *arg1, int arg
        return err;
 }
 
+static int
+sysctl_fakestack_enable(__unused struct sysctl_oid *oidp, __unused void *arg1, int __unused arg2, struct sysctl_req *req)
+{
+       int ch, err, val;
+
+       err = sysctl_io_number(req, fakestack_enabled, sizeof(fakestack_enabled), &val, &ch);
+       if (err == 0 && ch) {
+               fakestack_enabled = !!val;
+               __asan_option_detect_stack_use_after_return = !!val;
+       }
+
+       return err;
+}
+
 SYSCTL_DECL(kasan);
 SYSCTL_NODE(_kern, OID_AUTO, kasan, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "");
 
 SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, available, CTLFLAG_RD, NULL, KASAN, "");
-SYSCTL_INT(_kern_kasan, OID_AUTO, enabled, CTLFLAG_RD, &kasan_enabled, 0, "");
-SYSCTL_INT(_kern_kasan, OID_AUTO, quarantine, CTLFLAG_RW, &quarantine_enabled, 0, "");
-SYSCTL_LONG(_kern_kasan, OID_AUTO, memused, CTLFLAG_RD, &shadow_pages_used, "");
-SYSCTL_LONG(_kern_kasan, OID_AUTO, memtotal, CTLFLAG_RD, &shadow_pages_total, "");
-SYSCTL_LONG(_kern_kasan, OID_AUTO, kexts, CTLFLAG_RD, &kexts_loaded, "");
-
-SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, debug,         CTLFLAG_RD, NULL, KASAN_DEBUG, "");
-SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, zalloc,        CTLFLAG_RD, NULL, KASAN_ZALLOC, "");
-SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, kalloc,        CTLFLAG_RD, NULL, KASAN_KALLOC, "");
-SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, fakestack,     CTLFLAG_RD, NULL, FAKESTACK, "");
-SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, dynamicbl,     CTLFLAG_RD, NULL, KASAN_DYNAMIC_BLACKLIST, "");
-SYSCTL_COMPAT_INT(_kern_kasan, OID_AUTO, memintrinsics, CTLFLAG_RD, NULL, MEMINTRINSICS, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, enabled, CTLFLAG_RD, &kasan_enabled, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, checks, CTLFLAG_RW, &enabled_checks, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, quarantine, CTLFLAG_RW, &quarantine_enabled, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, report_ignored, CTLFLAG_RW, &report_ignored, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, free_yield_ms, CTLFLAG_RW, &free_yield, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, memused, CTLFLAG_RD, &shadow_pages_used, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, memtotal, CTLFLAG_RD, &shadow_pages_total, 0, "");
+SYSCTL_UINT(_kern_kasan, OID_AUTO, kexts, CTLFLAG_RD, &kexts_loaded, 0, "");
+SYSCTL_COMPAT_UINT(_kern_kasan, OID_AUTO, debug,     CTLFLAG_RD, NULL, KASAN_DEBUG, "");
+SYSCTL_COMPAT_UINT(_kern_kasan, OID_AUTO, zalloc,    CTLFLAG_RD, NULL, KASAN_ZALLOC, "");
+SYSCTL_COMPAT_UINT(_kern_kasan, OID_AUTO, kalloc,    CTLFLAG_RD, NULL, KASAN_KALLOC, "");
+SYSCTL_COMPAT_UINT(_kern_kasan, OID_AUTO, dynamicbl, CTLFLAG_RD, NULL, KASAN_DYNAMIC_BLACKLIST, "");
+
+SYSCTL_PROC(_kern_kasan, OID_AUTO, fakestack,
+               CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
+               0, 0, sysctl_fakestack_enable, "I", "");
 
 SYSCTL_PROC(_kern_kasan, OID_AUTO, test,
                CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
index bb048d860fda90e4592068c08ba35b5293906f09..102a31468ab6e630537e401194baf9af857c5527 100644 (file)
@@ -95,17 +95,28 @@ void kasan_notify_stolen(vm_offset_t top);
 void kasan_load_kext(vm_offset_t base, vm_size_t size, const void *bundleid);
 void kasan_unload_kext(vm_offset_t base, vm_size_t size);
 
+void kasan_unpoison(void *base, vm_size_t size);
 void kasan_poison_range(vm_offset_t base, vm_size_t sz, uint8_t flags);
 void kasan_notify_address(vm_offset_t address, vm_size_t size);
 void kasan_notify_address_nopoison(vm_offset_t address, vm_size_t size);
 void kasan_unpoison_stack(vm_offset_t stack, vm_size_t size);
+void kasan_unpoison_curstack(bool whole_stack);
 void kasan_unpoison_fakestack(thread_t thread);
 
+void kasan_fakestack_suspend(void);
+void kasan_fakestack_resume(void);
+
 struct kasan_test;
 void __kasan_runtests(struct kasan_test *, int numtests);
 
+
+typedef int (*pmap_traverse_callback)(vm_map_offset_t start,
+                                      vm_map_offset_t end,
+                                      void *context);
+int kasan_traverse_mappings(pmap_traverse_callback, void *context);
+
 #if XNU_KERNEL_PRIVATE
-extern long shadow_pages_total;
+extern unsigned shadow_pages_total;
 
 #if __arm64__
 void kasan_notify_address_zero(vm_offset_t, vm_size_t);
@@ -132,7 +143,6 @@ __END_DECLS
 
 /* thread interface */
 struct kasan_thread_data {
-       int in_fakestack;
        LIST_HEAD(fakestack_header_list, fakestack_header) fakestack_head;
 };
 struct kasan_thread_data *kasan_get_thread_data(thread_t);
@@ -146,19 +156,6 @@ void kasan_init_thread(struct kasan_thread_data *);
 # define NOKASAN
 #endif
 
-/*
- * Delimit areas of code that may do kasan-unsafe operations
- */
-__BEGIN_DECLS
-#if KASAN
-void kasan_unsafe_start(void);
-void kasan_unsafe_end(void);
-#else
-static inline void kasan_unsafe_start(void) {}
-static inline void kasan_unsafe_end(void) {}
-#endif
-__END_DECLS
-
 /*
  * ASAN callbacks - inserted by the compiler
  */
@@ -166,17 +163,24 @@ __END_DECLS
 extern int __asan_option_detect_stack_use_after_return;
 extern const uintptr_t __asan_shadow_memory_dynamic_address;
 
+#define KASAN_DECLARE_FOREACH_WIDTH(ret, func, ...) \
+       ret func ## 1(__VA_ARGS__); \
+       ret func ## 2(__VA_ARGS__); \
+       ret func ## 4(__VA_ARGS__); \
+       ret func ## 8(__VA_ARGS__); \
+       ret func ## 16(__VA_ARGS__); \
+
 __BEGIN_DECLS
-void __asan_report_load1(uptr p);
-void __asan_report_load2(uptr p);
-void __asan_report_load4(uptr p);
-void __asan_report_load8(uptr p);
-void __asan_report_load16(uptr p);
-void __asan_report_store1(uptr p);
-void __asan_report_store2(uptr p);
-void __asan_report_store4(uptr p);
-void __asan_report_store8(uptr p);
-void __asan_report_store16(uptr p);
+
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_load, uptr);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_store, uptr);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_store, uptr);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_exp_load, uptr, int32_t);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_exp_store, uptr, int32_t);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_exp_load, uptr, int32_t);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_exp_store, uptr, int32_t);
+KASAN_DECLARE_FOREACH_WIDTH(void, __asan_load, uptr);
+
 void __asan_report_load_n(uptr p, unsigned long size);
 void __asan_report_store_n(uptr p, unsigned long size);
 void __asan_handle_no_return(void);
@@ -208,22 +212,17 @@ void __asan_poison_stack_memory(uptr addr, size_t size);
 void __asan_unpoison_stack_memory(uptr addr, size_t size);
 void __asan_alloca_poison(uptr addr, uptr size);
 void __asan_allocas_unpoison(uptr top, uptr bottom);
-void __asan_load1(uptr);
-void __asan_load2(uptr);
-void __asan_load4(uptr);
-void __asan_load8(uptr);
-void __asan_load16(uptr);
 void __asan_loadN(uptr, size_t);
-void __asan_store1(uptr);
-void __asan_store2(uptr);
-void __asan_store4(uptr);
-void __asan_store8(uptr);
-void __asan_store16(uptr);
 void __asan_storeN(uptr, size_t);
 void __sanitizer_ptr_sub(uptr a, uptr b);
 void __sanitizer_ptr_cmp(uptr a, uptr b);
 void __sanitizer_annotate_contiguous_container(const void *beg, const void *end, const void *old_mid, const void *new_mid);
 
+void __asan_exp_loadN(uptr addr, size_t sz, int32_t e);
+void __asan_exp_storeN(uptr addr, size_t sz, int32_t e);
+void __asan_report_exp_load_n(uptr addr, unsigned long b, int32_t c);
+void __asan_report_exp_store_n(uptr addr, unsigned long b, int32_t c);
+
 void __asan_set_shadow_00(uptr, size_t);
 void __asan_set_shadow_f1(uptr, size_t);
 void __asan_set_shadow_f2(uptr, size_t);
@@ -232,10 +231,13 @@ void __asan_set_shadow_f5(uptr, size_t);
 void __asan_set_shadow_f8(uptr, size_t);
 
 void __asan_init_v5(void);
+void __asan_register_globals(uptr a, uptr b);
+void __asan_unregister_globals(uptr a, uptr b);
+void __asan_register_elf_globals(uptr a, uptr b, uptr c);
+void __asan_unregister_elf_globals(uptr a, uptr b, uptr c);
+
 void __asan_before_dynamic_init(uptr);
 void __asan_after_dynamic_init(void);
-void __asan_unregister_globals(uptr a, uptr b);
-void __asan_register_globals(uptr a, uptr b);
 void __asan_init(void);
 void __asan_unregister_image_globals(uptr);
 void __asan_register_image_globals(uptr);
index 97fc3a5612bff5634430d4f14be4494ce8d2821d..f4ad0fa059969246e6e6cf9c8313ba3248524a78 100644 (file)
 struct blacklist_entry {
        const char *kext_name;
        const char *func_name;
-       const unsigned type_mask;
+       access_t type_mask;
 
        /* internal */
        uint64_t count;
 };
 
 #include "kasan_blacklist_dynamic.h"
-static const size_t blacklist_entries = sizeof(blacklist)/sizeof(blacklist[0]);
+/* defines 'blacklist' and 'blacklist_entries' */
 
 decl_simple_lock_data(static, _dybl_lock);
+static access_t blacklisted_types; /* bitmap of access types with blacklist entries */
 
 static void
 dybl_lock(boolean_t *b)
@@ -349,19 +350,27 @@ addr_to_func(uintptr_t addr, const kernel_mach_header_t *mh)
        return cur_name;
 }
 
-bool NOINLINE
-kasan_is_blacklisted(unsigned mask)
+bool __attribute__((noinline))
+kasan_is_blacklisted(access_t type)
 {
        uint32_t nframes = 0;
        uintptr_t frames[MAX_FRAMES];
        uintptr_t *bt = frames;
-       nframes = backtrace(bt, MAX_FRAMES);
+
+       assert(__builtin_popcount(type) == 1);
+
+       if ((type & blacklisted_types) == 0) {
+               /* early exit for types with no blacklist entries */
+               return false;
+       }
+
+       nframes = backtrace_frame(bt, MAX_FRAMES, __builtin_frame_address(0));
        boolean_t flag;
 
-       if (nframes >= 2) {
-               /* ignore self and direct caller */
-               nframes -= 2;
-               bt += 2;
+       if (nframes >= 1) {
+               /* ignore direct caller */
+               nframes -= 1;
+               bt += 1;
        }
 
        struct blacklist_hash_entry *blhe = NULL;
@@ -372,7 +381,7 @@ kasan_is_blacklisted(unsigned mask)
        for (uint32_t i = 0; i < nframes; i++) {
                blhe = blacklist_hash_lookup(bt[i]);
                if (blhe) {
-                       if ((blhe->ble->type_mask & mask) != mask) {
+                       if ((blhe->ble->type_mask & type) != type) {
                                /* wrong type */
                                continue;
                        }
@@ -419,7 +428,7 @@ kasan_is_blacklisted(unsigned mask)
                        struct blacklist_entry *ble = &blacklist[j];
                        uint64_t count;
 
-                       if ((ble->type_mask & mask) != mask) {
+                       if ((ble->type_mask & type) != type) {
                                /* wrong type */
                                continue;
                        }
@@ -443,7 +452,7 @@ kasan_is_blacklisted(unsigned mask)
 
                        if (count == 0) {
                                printf("KASan: ignoring blacklisted violation (%s:%s [0x%lx] %d 0x%x)\n",
-                                               kextname, funcname, VM_KERNEL_UNSLIDE(bt[i]), i, mask);
+                                               kextname, funcname, VM_KERNEL_UNSLIDE(bt[i]), i, type);
                        }
 
                        return true;
@@ -454,11 +463,124 @@ kasan_is_blacklisted(unsigned mask)
        return false;
 }
 
+static void
+add_blacklist_entry(const char *kext, const char *func, access_t type)
+{
+       assert(kext || func);
+       struct blacklist_entry *ble = &blacklist[blacklist_entries++];
+
+       if (blacklist_entries > blacklist_max_entries) {
+               panic("KASan: dynamic blacklist entries exhausted\n");
+       }
+
+       if (kext) {
+               size_t sz = __nosan_strlen(kext) + 1;
+               if (sz > 1) {
+                       char *s = kalloc(sz);
+                       __nosan_strlcpy(s, kext, sz);
+                       ble->kext_name = s;
+               }
+       }
+
+       if (func) {
+               size_t sz = __nosan_strlen(func) + 1;
+               if (sz > 1) {
+                       char *s = kalloc(sz);
+                       __nosan_strlcpy(s, func, sz);
+                       ble->func_name = s;
+               }
+       }
+
+       ble->type_mask = type;
+}
+
+#define TS(x) { .type = TYPE_##x, .str = #x }
+
+static const struct {
+       const access_t type;
+       const char * const str;
+} typemap[] = {
+       TS(LOAD),
+       TS(STORE),
+       TS(MEMR),
+       TS(MEMW),
+       TS(STRR),
+       TS(STRW),
+       TS(KFREE),
+       TS(ZFREE),
+       TS(FSFREE),
+       TS(UAF),
+       TS(POISON_GLOBAL),
+       TS(POISON_HEAP),
+       TS(MEM),
+       TS(STR),
+       TS(READ),
+       TS(WRITE),
+       TS(RW),
+       TS(FREE),
+       TS(NORMAL),
+       TS(DYNAMIC),
+       TS(POISON),
+       TS(ALL),
+
+       /* convenience aliases */
+       { .type = TYPE_POISON_GLOBAL, .str = "GLOB" },
+       { .type = TYPE_POISON_HEAP,   .str = "HEAP" },
+};
+static size_t typemap_sz = sizeof(typemap)/sizeof(typemap[0]);
+
+static inline access_t
+map_type(const char *str)
+{
+       if (strlen(str) == 0) {
+               return TYPE_NORMAL;
+       }
+
+       /* convert type string to integer ID */
+       for (size_t i = 0; i < typemap_sz; i++) {
+               if (strcasecmp(str, typemap[i].str) == 0) {
+                       return typemap[i].type;
+               }
+       }
+
+       printf("KASan: unknown blacklist type `%s', assuming `normal'\n", str);
+       return TYPE_NORMAL;
+}
+
 void
 kasan_init_dybl(void)
 {
        simple_lock_init(&_dybl_lock, 0);
 
+       /*
+        * dynamic blacklist entries via boot-arg. Syntax is:
+        *  kasan.bl=kext1:func1:type1,kext2:func2:type2,...
+        */
+       char buf[256] = {};
+       char *bufp = buf;
+       if (PE_parse_boot_arg_str("kasan.bl", bufp, sizeof(buf))) {
+               char *kext;
+               while ((kext = strsep(&bufp, ",")) != NULL) {
+                       access_t type = TYPE_NORMAL;
+                       char *func = strchr(kext, ':');
+                       if (func) {
+                               *func++ = 0;
+                       }
+                       char *typestr = strchr(func, ':');
+                       if (typestr) {
+                               *typestr++ = 0;
+                               type = map_type(typestr);
+                       }
+                       add_blacklist_entry(kext, func, type);
+               }
+       }
+
+       /* collect bitmask of blacklisted types */
+       for (size_t j = 0; j < blacklist_entries; j++) {
+               struct blacklist_entry *ble = &blacklist[j];
+               blacklisted_types |= ble->type_mask;
+       }
+
        /* add the fake kernel kext */
        kasan_dybl_load_kext((uintptr_t)&_mh_execute_header, "__kernel__");
 }
@@ -466,7 +588,7 @@ kasan_init_dybl(void)
 #else /* KASAN_DYNAMIC_BLACKLIST */
 
 bool
-kasan_is_blacklisted(unsigned __unused mask)
+kasan_is_blacklisted(access_t __unused type)
 {
        return false;
 }
index 805255178145914f97e33e9eacfb847857b9a6bb..c696abe927c1828e9266e5fa0689e48a8650c4dd 100644 (file)
@@ -40,9 +40,8 @@ typedef uintptr_t uptr;
 /*
  * KASAN features and config
  */
-#define KASAN_DEBUG   1
+#define KASAN_DEBUG   0
 #define FAKESTACK     1
-#define MEMINTRINSICS 1
 /* KASAN_KALLOC defined in kasan.h */
 /* KASAN_ZALLOC defined in kasan.h */
 #define FAKESTACK_QUARANTINE (1 && FAKESTACK)
@@ -63,6 +62,13 @@ typedef uintptr_t uptr;
 # define STOLEN_MEM_BYTES    0
 #endif
 
+/* boot-args */
+#define KASAN_ARGS_FAKESTACK       0x0010U
+#define KASAN_ARGS_REPORTIGNORED   0x0020U
+#define KASAN_ARGS_NODYCHECKS      0x0100U
+#define KASAN_ARGS_NOPOISON_HEAP   0x0200U
+#define KASAN_ARGS_NOPOISON_GLOBAL 0x0400U
+
 #ifndef KASAN
 # error KASAN undefined
 #endif
@@ -74,61 +80,86 @@ typedef uintptr_t uptr;
 #define ADDRESS_FOR_SHADOW(x) (((x) - KASAN_SHIFT) << 3)
 #define SHADOW_FOR_ADDRESS(x) (uint8_t *)(((x) >> 3) + KASAN_SHIFT)
 
-#define NOINLINE __attribute__ ((noinline))
+#if KASAN_DEBUG
+# define NOINLINE __attribute__ ((noinline))
+#else
+# define NOINLINE
+#endif
 #define ALWAYS_INLINE inline __attribute__((always_inline))
 
 #define CLANG_MIN_VERSION(x) (defined(__apple_build_version__) && (__apple_build_version__ >= (x)))
 
 #define BIT(x) (1U << (x))
 
-enum kasan_access_type {
-       /* exactly one of these bits must be set */
-       TYPE_LOAD       = BIT(0),
-       TYPE_STORE      = BIT(1),
-       TYPE_KFREE      = BIT(2),
-       TYPE_ZFREE      = BIT(3),
-       TYPE_FSFREE     = BIT(4), /* fakestack free */
-       TYPE_MEMLD      = BIT(5), /* memory intrinsic - load */
-       TYPE_MEMSTR     = BIT(6), /* memory intrinsic - store */
-       TYPE_STRINGLD   = BIT(7), /* string intrinsic - load */
-       TYPE_STRINGSTR  = BIT(8), /* string intrinsic - store */
-       TYPE_TEST       = BIT(15),
+enum __attribute__((flag_enum)) kasan_access_types {
+       TYPE_LOAD    = BIT(0),  /* regular memory load */
+       TYPE_STORE   = BIT(1),  /* regular store */
+       TYPE_MEMR    = BIT(2),  /* memory intrinsic (read) */
+       TYPE_MEMW    = BIT(3),  /* memory intrinsic (write) */
+       TYPE_STRR    = BIT(4),  /* string intrinsic (read) */
+       TYPE_STRW    = BIT(5),  /* string intrinsic (write) */
+       TYPE_KFREE   = BIT(6),  /* kfree() */
+       TYPE_ZFREE   = BIT(7),  /* zfree() */
+       TYPE_FSFREE  = BIT(8),  /* fakestack free */
+
+       TYPE_UAF           = BIT(12),
+       TYPE_POISON_GLOBAL = BIT(13),
+       TYPE_POISON_HEAP   = BIT(14),
+       /* no TYPE_POISON_STACK, because the runtime does not control stack poisoning */
+       TYPE_TEST          = BIT(15),
 
        /* masks */
-       TYPE_LDSTR      = TYPE_LOAD|TYPE_STORE, /* regular loads and stores */
-       TYPE_FREE       = TYPE_KFREE|TYPE_ZFREE|TYPE_FSFREE,
-       TYPE_MEM        = TYPE_MEMLD|TYPE_MEMSTR,
-       TYPE_STRING     = TYPE_STRINGLD|TYPE_STRINGSTR,
-       TYPE_LOAD_ALL   = TYPE_LOAD|TYPE_MEMLD|TYPE_STRINGLD,
-       TYPE_STORE_ALL  = TYPE_STORE|TYPE_MEMSTR|TYPE_STRINGSTR,
-       TYPE_ALL        = ~0U
+       TYPE_MEM     = TYPE_MEMR|TYPE_MEMW,            /* memory intrinsics */
+       TYPE_STR     = TYPE_STRR|TYPE_STRW,            /* string intrinsics */
+       TYPE_READ    = TYPE_LOAD|TYPE_MEMR|TYPE_STRR,  /* all reads */
+       TYPE_WRITE   = TYPE_STORE|TYPE_MEMW|TYPE_STRW, /* all writes */
+       TYPE_RW      = TYPE_READ|TYPE_WRITE,           /* reads and writes */
+       TYPE_FREE    = TYPE_KFREE|TYPE_ZFREE|TYPE_FSFREE,
+       TYPE_NORMAL  = TYPE_RW|TYPE_FREE,
+       TYPE_DYNAMIC = TYPE_NORMAL|TYPE_UAF,
+       TYPE_POISON  = TYPE_POISON_GLOBAL|TYPE_POISON_HEAP,
+       TYPE_ALL     = ~0U,
 };
 
+enum kasan_violation_types {
+       REASON_POISONED =       0, /* read or write of poisoned data */
+       REASON_BAD_METADATA =   1, /* incorrect kasan metadata */
+       REASON_INVALID_SIZE =   2, /* free size did not match alloc size */
+       REASON_MOD_AFTER_FREE = 3, /* object modified after free */
+       REASON_MOD_OOB =        4, /* out of bounds modification of object */
+};
+
+typedef enum kasan_access_types access_t;
+typedef enum kasan_violation_types violation_t;
+
 bool kasan_range_poisoned(vm_offset_t base, vm_size_t size, vm_offset_t *first_invalid);
-void kasan_check_range(const void *x, size_t sz, unsigned access_type);
+void kasan_check_range(const void *x, size_t sz, access_t);
 void kasan_test(int testno, int fail);
 void kasan_handle_test(void);
-void kasan_unpoison_curstack(void);
 void kasan_free_internal(void **addrp, vm_size_t *sizep, int type, zone_t *, vm_size_t user_size, int locked, bool doquarantine);
 void kasan_poison(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t rightrz, uint8_t flags);
-void kasan_unpoison(void *base, vm_size_t size);
 void kasan_lock(boolean_t *b);
 void kasan_unlock(boolean_t b);
+bool kasan_lock_held(thread_t thread);
 void kasan_init_fakestack(void);
 
 /* dynamic blacklist */
 void kasan_init_dybl(void);
-bool kasan_is_blacklisted(unsigned type);
+bool kasan_is_blacklisted(access_t);
 void kasan_dybl_load_kext(uintptr_t addr, const char *kextname);
 void kasan_dybl_unload_kext(uintptr_t addr);
 
 /* arch-specific interface */
 void kasan_arch_init(void);
+bool kasan_is_shadow_mapped(uintptr_t shadowp);
 
 extern vm_address_t kernel_vbase;
 extern vm_address_t kernel_vtop;
 
-extern long shadow_pages_used;
+extern unsigned shadow_pages_used;
+
+/* boot-arg configurable */
+extern int fakestack_enabled;
 
 /* Describes the source location where a global is defined. */
 struct asan_global_source_location {
index 3f4c06bedcb10d9bbe59c3af88c60a6317be9a28..c71d9c4fbe1f4f39798f2316ba65cba3a360aedf 100755 (executable)
@@ -8,6 +8,8 @@ def type_map(x):
 
 re_comments=re.compile(r'#.*$')
 
+nentries = 0
+extra_entries = 5
 bl = file(sys.argv[1])
 
 print r'struct blacklist_entry blacklist[] = {'
@@ -35,12 +37,27 @@ for line in bl.readlines():
                func = '"' + func + '"'
 
        if ty == "":
-               ty = "all";
+               ty = "normal";
 
        print """       {{
                .kext_name = {},
                .func_name = {},
                .type_mask = {},
        }},""".format(kext, func, type_map(ty))
+       nentries += 1
+
+# add space for new entries added at runtime
+print ''
+print r'       /* Unused entries that can be populated at runtime */'
+for i in xrange(0, extra_entries):
+       print """       {{
+               .kext_name = {},
+               .func_name = {},
+               .type_mask = {},
+       }},""".format("NULL", "NULL", 0)
 
 print r'};'
+print
+
+print 'static size_t blacklist_entries = {};'.format(nentries)
+print 'static const size_t blacklist_max_entries = {};'.format(nentries + extra_entries)
diff --git a/san/tools/validate_blacklist.sh b/san/tools/validate_blacklist.sh
new file mode 100755 (executable)
index 0000000..8045241
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Ensure all blacklisted files exist. Paths with wildcards are ignored.
+# Run against a blacklist with fully-qualified paths.
+
+IFS=$'\n'
+
+blacklist_files=`sed -n -e '
+       # ignore paths with wildcards
+       /\*/ d
+
+       # strip leading 'src:'
+       /^src/ {
+               s/^src://
+               p
+       }
+' $1`
+
+ret=0
+
+for f in $blacklist_files ; do
+       if ! [[ -e $f ]] ; then
+               echo "KASan: blacklisted file $f not found" >&2
+               ret=1
+       fi
+done
+
+exit $ret
index e656f8393d70006474f19af2b681464654342493..5cae6252936d22f4ac3ef4b2f5524c01f98a63ee 100644 (file)
@@ -3841,13 +3841,14 @@ typedef int mpo_system_check_auditon_t(
   @param cred Subject credential
 
   Determine whether the subject identified by the credential can perform
-  performance-related tasks using the CHUD system call.
+  performance-related tasks using the CHUD system call.  This interface is
+  deprecated.
 
   @return Return 0 if access is granted, otherwise an appropriate value for
   errno should be returned.
 */
 typedef int mpo_system_check_chud_t(
-       kauth_cred_t cred
+   kauth_cred_t cred
 );
 /**
   @brief Access control check for obtaining the host control port
index afb3d6b887760e6299063390383be47515271a12..30383a3dbe1bc891bf253fd8cfd18a8fc2a6341d 100644 (file)
@@ -68,7 +68,8 @@ LLDBMACROS_PYTHON_FILES = $(LLDBMACROS_USERDEBUG_FILES) \
        usertaskgdbserver.py \
        waitq.py \
        pgtrace.py \
-       xnutriage.py
+       xnutriage.py \
+       zonetriage.py
 
 ifneq ($(PLATFORM),MacOSX)
        LLDBMACROS_PYTHON_FILES+= \
index 53a03fdf5b0baae1fe2ad74680ec310f59e437a8..ccff5196fd806ba817f719d3e8e61fe06fcaf7c4 100644 (file)
@@ -199,7 +199,7 @@ D. Kernel type summaries.
 ==========================
 i. Using summaries
 ------------------
-The lldb debugger provides ways for user to customize how a particular type of object be decsribed when printed. These are very useful in displaying complex and large structures
+The lldb debugger provides ways for user to customize how a particular type of object be described when printed. These are very useful in displaying complex and large structures
 where only certain fields are important based on some flag or value in some field or variable. The way it works is every time lldb wants to print an object it checks
 for registered summaries. We can define python functions and hook it up with lldb as callbacks for type summaries.  For example.
 
index 2142fa7ac827afda76de7fff0325a018b1ee7ddc..d4bec35c4cdd4da59fa888c792dd24c48d92117e 100755 (executable)
@@ -113,6 +113,14 @@ def print_alloc_free_entry(addr, orig_ptr):
 
 alloc_header_sz = 16
 
+def magic_for_addr(addr, xor):
+    magic = addr & 0xffff
+    magic ^= (addr >> 16) & 0xffff
+    magic ^= (addr >> 32) & 0xffff
+    magic ^= (addr >> 48) & 0xffff
+    magic ^= xor
+    return magic
+
 def print_alloc_info(_addr):
     addr = (_addr & ~0x7)
 
@@ -144,10 +152,7 @@ def print_alloc_info(_addr):
             print "No allocation found at 0x{:x} (found shadow {:x})".format(_addr, shbyte)
             return
 
-        live_magic = (addr & 0xffffffff) ^ 0xA110C8ED
-        free_magic = (addr & 0xffffffff) ^ 0xF23333D
-
-        if live_magic == unsigned(liveh.magic):
+        if magic_for_addr(addr, 0x3a65) == unsigned(liveh.magic):
             usz = unsigned(liveh.user_size)
             asz = unsigned(liveh.alloc_size)
             leftrz = unsigned(liveh.left_rz)
@@ -156,11 +161,12 @@ def print_alloc_info(_addr):
             if _addr >= base and _addr < base + asz:
                 footer = kern.GetValueFromAddress(addr + usz, 'struct kasan_alloc_footer *')
                 rightrz = asz - usz - leftrz
+                offset = _addr - addr
 
                 print "Live heap object"
                 print "Valid range: 0x{:x} -- 0x{:x} ({} bytes)".format(addr, addr + usz - 1, usz)
                 print "Total range: 0x{:x} -- 0x{:x} ({} bytes)".format(base, base + asz - 1, asz)
-                print "Offset:      {} bytes (shadow: 0x{:02x} {})".format(_addr - addr, _shbyte, _shstr)
+                print "Offset:      {} bytes (shadow: 0x{:02x} {}, remaining: {} bytes)".format(offset, _shbyte, _shstr, usz - offset)
                 print "Redzone:     {} / {} bytes".format(leftrz, rightrz)
 
                 btframes = unsigned(liveh.frames)
@@ -174,7 +180,7 @@ def print_alloc_info(_addr):
                 print_hexdump(base, asz, 0)
             return
 
-        elif free_magic == unsigned(freeh.magic):
+        elif magic_for_addr(addr, 0xf233) == unsigned(freeh.magic):
             asz = unsigned(freeh.size)
             if _addr >= addr and _addr < addr + asz:
                 print_alloc_free_entry(addr, _addr)
index 8732d5e947f4bb3b99fc91415f99a7696a3f658c..12a996c6935f35fb0e8910ada76d7a0495997ac1 100755 (executable)
@@ -200,12 +200,14 @@ class KCSubTypeElement(object):
         return KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag)
 
     @staticmethod
-    def FromBasicCtype(st_name, st_type, st_offset=0):
+    def FromBasicCtype(st_name, st_type, st_offset=0, legacy_size=None):
         if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64:
             raise ValueError("Invalid type passed %d" % st_type)
         st_size = struct.calcsize(KCSubTypeElement._unpack_formats[st_type])
         st_flag = 0
         retval = KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag, KCSubTypeElement._get_naked_element_value)
+        if legacy_size:
+            retval.legacy_size = legacy_size
         return retval
 
     @staticmethod
@@ -295,7 +297,8 @@ class KCTypeDescription(object):
         self.name = t_name
         self.totalsize = 0
         self.custom_JsonRepr = custom_repr
-        self.legacy_size = legacy_size
+        if legacy_size:
+            self.legacy_size = legacy_size
         self.merge = merge
         for e in self.elements:
             self.totalsize += e.GetTotalSize()
@@ -317,7 +320,8 @@ class KCTypeDescription(object):
 
     @staticmethod
     def FromKCTypeDescription(other, t_type_id, t_name):
-        retval = KCTypeDescription(t_type_id, other.elements, t_name, other.custom_JsonRepr)
+        retval = KCTypeDescription(t_type_id, other.elements, t_name, other.custom_JsonRepr,
+                                   legacy_size=getattr(other, 'legacy_size', None))
         return retval
 
     def ShouldMerge(self):
@@ -328,7 +332,7 @@ class KCTypeDescription(object):
             padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK)
             if padding:
                 base_data = base_data[:-padding]
-        elif self.legacy_size and len(base_data) == self.legacy_size + ((-self.legacy_size) & 0xf):
+        elif hasattr(self, 'legacy_size') and len(base_data) == self.legacy_size + ((-self.legacy_size) & 0xf):
             base_data = base_data[:self.legacy_size]
         if self.custom_JsonRepr:
             return self.custom_JsonRepr([e.GetValue(base_data) for e in self.elements])
@@ -497,10 +501,8 @@ class KCObject(object):
             element_arr = []
             for i in range(u_d[1]):
                 e = KCSubTypeElement.FromBinaryTypeData(self.i_data[40+(i*40):])
-                #print str(e)
                 element_arr.append(e)
             type_desc = KCTypeDescription(u_d[0], element_arr, self.obj['name'])
-            #print str(type_desc)
             self.obj['fields'] = [str(e) for e in element_arr]
             KNOWN_TYPES_COLLECTION[type_desc.GetTypeID()] = type_desc
             logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name))
@@ -511,9 +513,9 @@ class KCObject(object):
             if e_t not in LEGAL_OLD_STYLE_ARRAY_TYPES:
                 raise Exception, "illegal old-style array type: %s (0x%x)" % (GetTypeNameForKey(e_t), e_t)
             e_c = self.i_flags & 0xffffffff
-            e_s = KNOWN_TYPES_COLLECTION[e_t].sizeof()
+            e_s = KNOWN_TYPES_COLLECTION[e_t].legacy_size
             if e_s * e_c > self.i_size:
-                raise Excpetion, "array too small for its count"
+                raise Exception("array too small for its count")
             self.obj['typeID'] = e_t
             self.i_name = GetTypeNameForKey(e_t)
             self.i_type = e_t
@@ -824,8 +826,11 @@ KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT')]
     KCSubTypeElement.FromBasicCtype('tds_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 45),
     KCSubTypeElement.FromBasicCtype('tds_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 46),
     KCSubTypeElement.FromBasicCtype('tds_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 47),
+    KCSubTypeElement.FromBasicCtype('tds_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 48),
+    KCSubTypeElement.FromBasicCtype('tds_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 56),
 ),
-    'thread_delta_snapshot'
+    'thread_delta_snapshot',
+    legacy_size = 48
 )
 
 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT'), (
@@ -855,14 +860,16 @@ KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64')] = KCTyp
     KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0),
     KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1)
 ),
-    'dyld_load_info'
+    'dyld_load_info',
+    legacy_size = 24
 )
 
 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO'), (
     KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0),
     KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 4, 1)
 ),
-    'dyld_load_info'
+    'dyld_load_info',
+    legacy_size = 20
 )
 
 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO'), (
@@ -882,7 +889,7 @@ KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO')]
 )
 
 KNOWN_TYPES_COLLECTION[0x33] = KCSubTypeElement('mach_absolute_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)
-KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement.FromBasicCtype('donating_pids', KCSUBTYPE_TYPE.KC_ST_INT32)
+KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement.FromBasicCtype('donating_pids', KCSUBTYPE_TYPE.KC_ST_INT32, legacy_size=4)
 
 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_USECS_SINCE_EPOCH')] = KCSubTypeElement('usecs_since_epoch', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)
 
@@ -890,7 +897,8 @@ KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')] = KCT
     KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32),
     KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT32, 4)
 ),
-    'kernel_stack_frames'
+    'kernel_stack_frames',
+    legacy_size = 8
 )
 
 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR'), (
@@ -916,7 +924,8 @@ KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')] = K
     KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64),
     KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)
 ),
-    'kernel_stack_frames'
+    'kernel_stack_frames',
+    legacy_size = 16
 )
 
 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64')] = KCTypeDescription.FromKCTypeDescription(
@@ -1281,7 +1290,7 @@ def formatWaitInfo(info):
         else:
             s += "unknown port"
     elif type == kThreadWaitSemaphore:
-        s += "semaphore port %x" % context
+        s += "semaphore port %x " % context
         if owner:
             s += "owned by pid %d" % owner
         else:
@@ -1294,13 +1303,13 @@ def formatWaitInfo(info):
         s += "krwlock %x for upgrading" % context
     elif type == kThreadWaitUserLock:
         if owner:
-            s += "unfair lock %x owned by pid %d" % (context, owner)
+            s += "unfair lock %x owned by thread %d" % (context, owner)
         else:
             s += "spin lock %x" % context
     elif type == kThreadWaitPThreadMutex:
         s += "pthread mutex %x" % context
         if owner:
-            s += " owned by pid %d" % owner
+            s += " owned by thread %d" % owner
         else:
             s += " with unknown owner"
     elif type == kThreadWaitPThreadRWLockRead:
@@ -1645,6 +1654,8 @@ def prettify(data):
                 value = '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(value)
             elif 'address' in key.lower() and isinstance(value, (int, long)):
                 value = '0x%X' % value
+            elif key == 'thread_waitinfo':
+                value = map(formatWaitInfo, value)
             else:
                 value = prettify(value);
             newdata[key] = value
index 1010c6eb320ec8b33057b4554ca685194dc770c7..b86e1a80d694a231ec059d263bf8577fdd4a09b4 100755 (executable)
@@ -171,8 +171,6 @@ def GetASTSummary(ast):
         B - AST_BSD
         K - AST_KPERF
         M - AST_MACF
-        C - AST_CHUD
-        C - AST_CHUD_URGENT
         G - AST_GUARD
         T - AST_TELEMETRY_USER
         T - AST_TELEMETRY_KERNEL
@@ -185,7 +183,7 @@ def GetASTSummary(ast):
     out_string = ""
     state = int(ast)
     thread_state_chars = {0x0:'', 0x1:'P', 0x2:'Q', 0x4:'U', 0x8:'H', 0x10:'Y', 0x20:'A',
-                          0x40:'L', 0x80:'B', 0x100:'K', 0x200:'M', 0x400:'C', 0x800:'C',
+                          0x40:'L', 0x80:'B', 0x100:'K', 0x200:'M',
                           0x1000:'G', 0x2000:'T', 0x4000:'T', 0x8000:'T', 0x10000:'S',
                           0x20000: 'D', 0x40000: 'I', 0x80000: 'E'}
     state_str = ''
@@ -451,6 +449,14 @@ def GetResourceCoalitionSummary(coal, verbose=False):
     out_string += "\n\t  total_tasks {0: <d}\n\t  dead_tasks {1: <d}\n\t  active_tasks {2: <d}".format(coal.r.task_count, coal.r.dead_task_count, coal.r.task_count - coal.r.dead_task_count)
     out_string += "\n\t  last_became_nonempty_time {0: <d}\n\t  time_nonempty {1: <d}".format(coal.r.last_became_nonempty_time, coal.r.time_nonempty)
     out_string += "\n\t  cpu_ptime {0: <d}".format(coal.r.cpu_ptime)
+    if verbose:
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_DEFAULT] {0: <d}".format(coal.r.cpu_time_eqos[0])
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_MAINTENANCE] {0: <d}".format(coal.r.cpu_time_eqos[1])
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_BACKGROUND] {0: <d}".format(coal.r.cpu_time_eqos[2])
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_UTILITY] {0: <d}".format(coal.r.cpu_time_eqos[3])
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_LEGACY] {0: <d}".format(coal.r.cpu_time_eqos[4])
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_USER_INITIATED] {0: <d}".format(coal.r.cpu_time_eqos[5])
+        out_string += "\n\t  cpu_time_effective[THREAD_QOS_USER_INTERACTIVE] {0: <d}".format(coal.r.cpu_time_eqos[6])
     out_string += "\n\t  Tasks:\n\t\t"
     tasks = GetCoalitionTasks(addressof(coal.r.tasks), 0, thread_details)
     out_string += "\n\t\t".join(tasks)
index 8b5d5bb1e29849e73c1bdfa46458b94e97983cf2..1806464fd72bbf38b64da88bf739cbb16312a764 100755 (executable)
@@ -821,4 +821,5 @@ from pgtrace import *
 from xnutriage import *
 from kevent import *
 from ntstat import *
+from zonetriage import *
 
diff --git a/tools/lldbmacros/zonetriage.py b/tools/lldbmacros/zonetriage.py
new file mode 100755 (executable)
index 0000000..ef6f52d
--- /dev/null
@@ -0,0 +1,124 @@
+"""
+    Triage Macros for zone related panics
+    
+    Supported panic strings from xnu/osfmk/kern/zalloc.c: 
+        "a freed zone element has been modified in zone %s: expected %p but found %p, bits changed %p, at offset %d of %d in element %p, cookies %p %p" and
+        "zalloc: zone map exhausted while allocating from zone %s, likely due to memory leak in zone %s (%lu total bytes, %d elements allocated)"
+    These macros are dependant on the above panic strings. If the strings are modified in any way, this script must be updated to reflect the change.
+    
+    To support more zone panic strings:
+        1.  Add the panic string regex to the globals and include in the named capture group 'zone' (the zone to be 
+            logged) as well as any other info necessary to parse out of the panic string.
+        2.  Add a check for the panic string regex in ZoneTriage(), which then calls into the function you create.
+        3.  Add a check for the panic string regex in CheckZoneBootArgs() which sets the variable panic_string_regex to your 
+            panic string regex if found.
+        4.  Create a function that can be called either through the zonetriage macro ZoneTriage() or using its own macro. 
+            This function should handle all lldb commands you want to run for this type of zone panic.
+"""
+from xnu import *
+import sys, shlex
+from utils import *
+import xnudefines
+import re
+import os.path
+
+## Globals
+panic_string = None
+## If the following panic strings are modified in xnu/osfmk/kern/zalloc.c, they must be updated here to reflect the change.
+zone_element_modified = ".*a freed zone element has been modified in zone (?P<zone>.+): expected (0x)?([0-9A-Fa-f]*)? but found (0x)?([0-9A-Fa-f]*)?, bits changed (0x)?([0-9A-Fa-f]*)?, at offset ([0-9]*)? of ([0-9]*)? in element (?P<element>0x[0-9A-Fa-f]*), cookies (0x)?([0-9A-Fa-f]*)? (0x)?([0-9A-Fa-f]*)?.*"
+zone_map_exhausted = ".*zalloc: zone map exhausted while allocating from zone .+, likely due to memory leak in zone (?P<zone>.+) \(([0-9]*)? total bytes, ([0-9]*)? elements allocated\).*"
+
+# Macro: zonetriage, zonetriage_freedelement, zonetriage_memoryleak
+@lldb_command('zonetriage')
+def ZoneTriage(cmd_args=None):
+    """ Calls function specific to type of zone panic based on the panic string
+    """
+    global panic_string
+    if panic_string is None:
+        try:
+            panic_string = lldb_run_command("paniclog").split('\n', 1)[0]
+        except:
+            return
+    if re.match(zone_element_modified, panic_string) is not None:
+        ZoneTriageFreedElement()
+    elif re.match(zone_map_exhausted, panic_string) is not None:
+        ZoneTriageMemoryLeak()
+    else:
+        print "zonetriage does not currently support this panic string."
+
+@lldb_command('zonetriage_freedelement')
+def ZoneTriageFreedElement(cmd_args=None):
+    """ Runs zstack_findelem on the element and zone being logged based on the panic string regex
+    """
+    global panic_string
+    if panic_string is None:
+        try:
+            panic_string = lldb_run_command("paniclog").split('\n', 1)[0]
+        except:
+            return
+    CheckZoneBootArgs()
+    ## Run showzonesbeinglogged. 
+    print "(lldb) zstack_showzonesbeinglogged\n%s\n" % lldb_run_command("zstack_showzonesbeinglogged")
+    ## Capture zone and element from panic string.
+    values = re.search(zone_element_modified, panic_string)
+    if values is None or 'zone' not in values.group() or 'element' not in values.group():
+        return
+    element = values.group('element')
+    zone = values.group('zone')
+    btlog = FindZoneBTLog(zone)
+    if btlog is not None:
+        print "(lldb) zstack_findelem " + btlog + " " + element
+        findelem_output = lldb_run_command("zstack_findelem " + btlog + " " + element)
+        findelem_output = re.sub('Scanning is ongoing. [0-9]* items scanned since last check.\n', '', findelem_output)
+        print findelem_output
+
+@lldb_command('zonetriage_memoryleak')
+def ZoneTriageMemoryLeak(cmd_args=None):
+    """ Runs zstack_findtop and zstack_findleak on all zones being logged
+    """
+    global kern
+    CheckZoneBootArgs()
+    ## Run showzonesbeinglogged. 
+    print "(lldb) zstack_showzonesbeinglogged\n%s\n" % lldb_run_command("zstack_showzonesbeinglogged")
+    for zval in kern.zones:
+        if zval.zlog_btlog:
+            print '%s:' % zval.zone_name
+            print "(lldb) zstack_findtop -N 5 0x%lx" % zval.zlog_btlog
+            print lldb_run_command("zstack_findtop -N 5 0x%lx" % zval.zlog_btlog)
+            print "(lldb) zstack_findleak 0x%lx" % zval.zlog_btlog
+            print lldb_run_command("zstack_findleak 0x%lx" % zval.zlog_btlog)
+
+def CheckZoneBootArgs(cmd_args=None):
+    """ Check boot args to see if zone is being logged, if not, suggest new boot args
+    """
+    global panic_string
+    if panic_string is None:
+        try:
+            panic_string = lldb_run_command("paniclog").split('\n', 1)[0]
+        except:
+            return
+    panic_string_regex = ""
+    if re.match(zone_element_modified, panic_string) is not None:
+        panic_string_regex = zone_element_modified
+    if re.match(zone_map_exhausted, panic_string) is not None:
+        panic_string_regex = zone_map_exhausted
+    values = re.search(panic_string_regex, panic_string)
+    if values is None or 'zone' not in values.group():
+        return
+    zone = values.group('zone')
+    bootargs = lldb_run_command("showbootargs")
+    correct_boot_args = re.search('zlog([1-9]|10)?=' + re.sub(' ', '.', zone), bootargs)
+    if correct_boot_args is None:
+        print "Current boot-args:\n" + bootargs
+        print "You may need to include: -zc -zp zlog([1-9]|10)?=" + re.sub(' ', '.', zone)
+
+def FindZoneBTLog(zone):
+    """ Returns the btlog address in the format 0x%lx for the zone name passed as a parameter
+    """
+    global kern
+    for zval in kern.zones:
+        if zval.zlog_btlog:
+            if zone == "%s" % zval.zone_name:
+                return "0x%lx" % zval.zlog_btlog
+    return None
+# EndMacro: zonetriage, zonetriage_freedelement, zonetriage_memoryleak
index 738f48adde47f2e90a3be4e5e1b0144f0db9a3e3..80cb4dde60d281cdc32b0917bd17895b91f4db3a 100755 (executable)
@@ -15,7 +15,7 @@ fi
 
 echo "Using ${CLANGFORMAT} to reindent, using concurrency of ${CPUS}"
 
-find -x . \! \( \( -name BUILD -o -name EXTERNAL_HEADERS -o -name libMicro -o -name zlib -o -name .svn -o -name .git -o -name cscope.\* -o -name \*~ \) -prune \) -type f \( -name \*.c -o -name \*.cpp \) -print0 | \
+find -x . \! \( \( -name BUILD -o -name EXTERNAL_HEADERS -o -name zlib -o -name .svn -o -name .git -o -name cscope.\* -o -name \*~ \) -prune \) -type f \( -name \*.c -o -name \*.cpp \) -print0 | \
     xargs -0 -P "${CPUS}" -n 10 "${CLANGFORMAT}" -style=file -i
 ret=$?
 
index a6f4012ab5b5aa36f3bb99a1470b2f9ca13d451c..d862d076746765d4907153bc1a9580c9e4396018 100644 (file)
@@ -34,6 +34,8 @@ CODESIGN_ALLOCATE:=$(shell xcrun -sdk "$(TARGETSDK)" -find codesign_allocate)
 # to have custom compiler flags to
 # target: OTHER_CFLAGS += <my flags>
 
+atm_diagnostic_flag: OTHER_CFLAGS += drop_priv.c
+
 avx: INVALID_ARCHS = i386
 avx: OTHER_CFLAGS += -mavx512f -mavx512bw -mavx512vl
 avx: OTHER_CFLAGS += -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
@@ -41,18 +43,20 @@ avx: CONFIG_FLAGS := $(filter-out -O%,$(CONFIG_FLAGS))
 # Level 2 optimization must be used to prevent compiler from generating
 # invalid instructions when compiling with AVX-512 flags.
 avx: CONFIG_FLAGS += -O2
+# Disable vzeroupper insertion to work around rdar://problem/35035096
+avx: CONFIG_FLAGS += -mllvm -x86-use-vzeroupper=0
 ifneq (osx,$(TARGET_NAME))
 EXCLUDED_SOURCES += avx.c
 endif
 
 backtracing: OTHER_LDFLAGS += -framework CoreSymbolication
 
-data_protection: OTHER_LDFLAGS += -framework IOKit
+data_protection: OTHER_LDFLAGS += -ldarwintest_utils -framework IOKit
 
 kdebug: INVALID_ARCHS = i386
 kdebug: OTHER_LDFLAGS = -framework ktrace
 
-EXCLUDED_SOURCES += kperf_helpers.c xnu_quick_test_helpers.c
+EXCLUDED_SOURCES += drop_priv.c kperf_helpers.c xnu_quick_test_helpers.c
 
 ifeq ($(PLATFORM),iPhoneOS)
 CONFIG_FREEZE_DEFINE:= -DCONFIG_FREEZE
@@ -62,6 +66,7 @@ EXCLUDED_SOURCES += jumbo_va_spaces_28530648.c
 endif
 
 perf_compressor: OTHER_CFLAGS += $(CONFIG_FREEZE_DEFINE)
+perf_compressor: OTHER_LDFLAGS += -ldarwintest_utils
 perf_compressor: CODE_SIGN_ENTITLEMENTS=./private_entitlement.plist
 
 stackshot: OTHER_LDFLAGS += -lkdd -framework Foundation
@@ -119,9 +124,19 @@ stackshot_idle_25570396: OTHER_LDFLAGS += -lkdd -framework Foundation
 
 stackshot_block_owner_14362384: INVALID_ARCHS = i386
 stackshot_block_owner_14362384: OTHER_LDFLAGS += -framework Foundation -lpthread -lkdd
+ifeq ($(PLATFORM),MacOSX)
+stackshot_block_owner_14362384: OTHER_LDFLAGS += -lpcre
+endif
+
+all: $(DSTROOT)/usr/local/bin/kcdata
+
+$(DSTROOT)/usr/local/bin/kcdata: $(SRCROOT)/../../lldbmacros/kcdata.py
+       mkdir -p $(dir $@)
+       cp $< $@
+       chmod a+x $@
 
 xnu_quick_test: OTHER_CFLAGS += xnu_quick_test_helpers.c
-       
+
 ifeq ($(PLATFORM),iPhoneOS)
 OTHER_TEST_TARGETS += jumbo_va_spaces_28530648_unentitled
 jumbo_va_spaces_28530648: CODE_SIGN_ENTITLEMENTS = jumbo_va_spaces_28530648.entitlements
@@ -135,6 +150,9 @@ endif
 
 task_info_28439149: CODE_SIGN_ENTITLEMENTS = ./task_for_pid_entitlement.plist
 
+proc_info: CODE_SIGN_ENTITLEMENTS = ./task_for_pid_entitlement.plist
+proc_info: OTHER_LDFLAGS += -ldarwintest_utils
+
 disk_mount_conditioner: disk_mount_conditioner*
 disk_mount_conditioner: CODE_SIGN_ENTITLEMENTS=./disk_mount_conditioner-entitlements.plist
 disk_mount_conditioner: OTHER_LDFLAGS += -ldarwintest_utils
@@ -148,10 +166,24 @@ disk_mount_conditioner_unentitled: disk_mount_conditioner.c
 work_interval_test: CODE_SIGN_ENTITLEMENTS = work_interval_test.entitlements
 work_interval_test: OTHER_CFLAGS += -DENTITLED=1
 
+settimeofday_29193041: OTHER_CFLAGS += drop_priv.c
+
 settimeofday_29193041_entitled: CODE_SIGN_ENTITLEMENTS = settimeofday_29193041.entitlements
+settimeofday_29193041_entitled: OTHER_CFLAGS += drop_priv.c
+
 thread_group_set_32261625: OTHER_LDFLAGS = -framework ktrace
 thread_group_set_32261625: INVALID_ARCHS = i386
 
 task_info: CODE_SIGN_ENTITLEMENTS = task_for_pid_entitlement.plist
 
+socket_bind_35243417: CODE_SIGN_ENTITLEMENTS = network_entitlements.plist
+socket_bind_35685803: CODE_SIGN_ENTITLEMENTS = network_entitlements.plist
+
+ifneq (osx,$(TARGET_NAME))
+EXCLUDED_SOURCES += no32exec_35914211.c no32exec_35914211_helper.c
+endif
+
+no32exec_35914211_helper:  INVALID_ARCHS = x86_64
+no32exec_35914211:  INVALID_ARCHS = i386
+
 include $(DEVELOPER_DIR)/AppleInternal/Makefiles/darwintest/Makefile.targets
diff --git a/tools/tests/darwintests/atm_diagnostic_flag.c b/tools/tests/darwintests/atm_diagnostic_flag.c
new file mode 100644 (file)
index 0000000..864ffd6
--- /dev/null
@@ -0,0 +1,78 @@
+#include <darwintest.h>
+
+#include <mach/mach_error.h>
+#include <mach/mach_host.h>
+
+T_GLOBAL_META(T_META_NAMESPACE("xnu.debugging"));
+
+/*
+ * The low 8 bits may be in use, so modify one
+ * of the upper 8 bits to ensure round-tripping. 
+ */
+#define LIBTRACE_PRIVATE_DATA  0x01000000
+
+extern void drop_priv(void);
+
+static bool _needs_reset;
+static uint32_t _original;
+
+static uint32_t
+_save_atm_diagnostic_flag(void)
+{
+    kern_return_t kr;
+    kr = host_get_atm_diagnostic_flag(mach_host_self(), &_original);
+    T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "host_get_atm_diagnostic_flag()");
+    T_LOG("Original ATM diagnostic flag: 0x%08x", _original);
+    return _original;
+}
+
+static kern_return_t
+_mutate_atm_diagnostic_flag(uint32_t v)
+{
+    T_LOG("Try to set ATM diagnostic flag to: 0x%08x", v);
+    kern_return_t kr = host_set_atm_diagnostic_flag(mach_host_self(), v);
+    if (kr == KERN_SUCCESS) _needs_reset = true;
+    return kr;
+}
+
+static void
+_reset_atm_diagnostic_flag(void)
+{
+    if (!_needs_reset) return;
+    T_LOG("Reset ATM diagnostic flag to: 0x%08x", _original);
+    kern_return_t kr;
+    kr = host_set_atm_diagnostic_flag(mach_host_self(), _original);
+    if (kr != KERN_SUCCESS) {
+        T_ASSERT_FAIL("host_set_atm_diagnostic_flag() failed: %s",
+                mach_error_string(kr));
+    }
+}
+
+T_DECL(toggle_atm_diagnostic_flag,
+        "change the atm_diagnostic_flag, which should use the commpage",
+        T_META_ASROOT(true))
+{
+    T_ATEND(_reset_atm_diagnostic_flag);
+    uint32_t f = _save_atm_diagnostic_flag();
+    f ^= LIBTRACE_PRIVATE_DATA;
+    kern_return_t kr = _mutate_atm_diagnostic_flag(f);
+    if (kr == KERN_NOT_SUPPORTED) {
+        T_SKIP("Seems ATM is disabled on this platform. "
+                "Ignoring host_set_atm_diagnostic_flag functionality. "
+                "Bailing gracefully.");
+    }
+    T_EXPECT_MACH_SUCCESS(kr, "Set atm_diagnostic_flag");
+}
+
+T_DECL(unprivileged_atm_diagnostic_flag,
+        "expect to fail to set the atm_diagnostic_flag",
+        T_META_ASROOT(false))
+{
+    drop_priv();
+    T_ATEND(_reset_atm_diagnostic_flag);
+    uint32_t f = _save_atm_diagnostic_flag();
+    f ^= LIBTRACE_PRIVATE_DATA;
+    kern_return_t kr = _mutate_atm_diagnostic_flag(f);
+    T_EXPECT_MACH_ERROR(KERN_INVALID_ARGUMENT, kr,
+            "Deny change to atm_diagnostic_flag");
+}
index 331c4809f2dd9cc4c7b6579c8f5ff88a892ee591..c9a69fee74cf2ecb16083164d1880029ed7c6dec 100644 (file)
@@ -1,4 +1,5 @@
 #include <darwintest.h>
+#include <darwintest_utils.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
@@ -577,10 +578,10 @@ setup(void) {
                T_SKIP("Data protection not supported on this system");
        }
 
-       T_ASSERT_NE(
+       T_ASSERT_EQ(
                has_passcode(),
-               -1,
-               "No passcode set"
+               0,
+               "Device should not have existing passcode"
        );
 
        T_ASSERT_EQ(
@@ -1043,55 +1044,32 @@ end:
 }
 
 /*
- * Just a wrapper around fork/exec for separate
- * cmds that may require entitlements.
+ * Helper function for launching tools
  */
 int
 spawn_proc(char * const command[]) {
-       int child_result = -1;
-       int result = -1;
-       pid_t child = -1;
-
-       T_LOG("Spawning %s", command[0]);
-
-       child = fork();
-
-       if(child == -1) {
-               T_LOG("%s(%s): fork() failed", __func__, command[0]);
+       pid_t pid           = 0;
+       int launch_tool_ret = 0;
+       bool waitpid_ret    = true;
+       int status          = 0;
+       int signal          = 0;
+       int timeout         = 30;
+
+       launch_tool_ret = dt_launch_tool(&pid, command, false, NULL, NULL);
+       T_EXPECT_EQ(launch_tool_ret, 0, "launch tool: %s", command[0]);
+       if(launch_tool_ret != 0) {
                return 1;
-       } else if(child == 0) {
-               /*
-                * TODO: This keeps keystorectl from bombarding us with key
-                * state changes, but there must be a better way of doing
-                * this; killing stderr is a bit nasty, and if keystorectl
-                * fails, we want all the information we can get.
-                */
-               fclose(stderr);
-               fclose(stdin);
-
-               /*
-                * Use the first argument in 'command' array as the path to
-                * execute, as it could be invoking keystorectl OR keybagdTest
-                * depending on whether or not we need to apply a grace period.
-                * In the "lock" case we must use keybagdTest to ensure it's
-                * giving people the grace period.
-                */
-               execv(command[0], command);
-               T_WITH_ERRNO;
-               T_ASSERT_FAIL("child failed to execv %s", command[0]);
        }
 
-       if(waitpid(child, &child_result, 0) != child) {
-               T_LOG(
-                       "%s(%s): waitpid(%d) failed",
-                       __func__, command[0], child
-               );
-               return 1;
-       } else if(WEXITSTATUS(child_result)) {
-               T_LOG(
-                       "%s(%s): child exited %d",
-                       __func__, command[0], WEXITSTATUS(child_result)
-               );
+       waitpid_ret = dt_waitpid(pid, &status, &signal, timeout);
+       T_EXPECT_TRUE(waitpid_ret, "%s should succeed", command[0]);
+       if(waitpid_ret == false) {
+               if(status != 0) {
+                       T_LOG("%s exited %d", command[0], status);
+               }
+               if(signal != 0) {
+                       T_LOG("%s received signal %d", command[0], signal);
+               }
                return 1;
        }
 
diff --git a/tools/tests/darwintests/drop_priv.c b/tools/tests/darwintests/drop_priv.c
new file mode 100644 (file)
index 0000000..7bb499c
--- /dev/null
@@ -0,0 +1,59 @@
+#include <darwintest.h>
+
+#include <TargetConditionals.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <unistd.h>
+
+#if !TARGET_OS_OSX
+#include <pwd.h>
+#include <sys/types.h>
+#include <uuid/uuid.h>
+#endif
+
+#if TARGET_OS_OSX
+#define INVOKER_UID "SUDO_UID"
+#define INVOKER_GID "SUDO_GID"
+#define ID_MAX (unsigned long)UINT_MAX
+static unsigned
+_get_sudo_invoker(const char *var)
+{
+    char *value_str = getenv(var);
+    T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(value_str,
+            "Not running under sudo, getenv(\"%s\") failed", var);
+    T_QUIET; T_ASSERT_NE_CHAR(*value_str, '\0',
+            "getenv(\"%s\") returned an empty string", var);
+
+    char *endp;
+    unsigned long value = strtoul(value_str, &endp, 10);
+    T_QUIET; T_WITH_ERRNO; T_ASSERT_EQ_CHAR(*endp, '\0',
+            "strtoul(\"%s\") not called on a valid number", value_str);
+    T_QUIET; T_WITH_ERRNO; T_ASSERT_NE_ULONG(value, ULONG_MAX,
+            "strtoul(\"%s\") overflow", value_str);
+
+    T_QUIET; T_ASSERT_NE_ULONG(value, 0ul, "%s invalid", var);
+    T_QUIET; T_ASSERT_LT_ULONG(value, ID_MAX, "%s invalid", var);
+    return (unsigned)value;
+}
+#endif /* TARGET_OS_OSX */
+
+void
+drop_priv(void);
+void
+drop_priv(void)
+{
+#if TARGET_OS_OSX
+    uid_t lower_uid = _get_sudo_invoker(INVOKER_UID);
+    gid_t lower_gid = _get_sudo_invoker(INVOKER_GID);
+#else
+    struct passwd *pw = getpwnam("mobile");
+    T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(pw, "getpwnam(\"mobile\")");
+    uid_t lower_uid = pw->pw_uid;
+    gid_t lower_gid = pw->pw_gid;
+#endif
+    T_ASSERT_POSIX_SUCCESS(setgid(lower_gid), "Change group to %u", lower_gid);
+    T_ASSERT_POSIX_SUCCESS(setuid(lower_uid), "Change user to %u", lower_uid);
+}
diff --git a/tools/tests/darwintests/freebsd_waitpid_nohang.c b/tools/tests/darwintests/freebsd_waitpid_nohang.c
new file mode 100644 (file)
index 0000000..9aa55e1
--- /dev/null
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2016 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/wait.h>
+
+#include <darwintest.h>
+#include <signal.h>
+#include <unistd.h>
+
+T_DECL(waitpid_nohang, "FreeBSDarwin--waitpid_nohang")
+{
+       pid_t child, pid;
+       int status, r;
+       siginfo_t siginfo;
+
+       child = fork();
+       T_ASSERT_POSIX_SUCCESS(child, "child forked successfully");
+       if (child == 0) {
+               sleep(10);
+               _exit(1);
+       }
+
+       status = 42;
+       pid = waitpid(child, &status, WNOHANG);
+       T_ASSERT_POSIX_ZERO(pid, "waitpid call is successful");
+       T_EXPECT_EQ(status, 42, "status is unaffected as expected");
+
+       r = kill(child, SIGTERM);
+       T_ASSERT_POSIX_ZERO(r, "signal sent successfully");
+       r = waitid(P_PID, (id_t)child, &siginfo, WEXITED | WNOWAIT);
+       T_ASSERT_POSIX_SUCCESS(r, "waitid call successful");
+
+       status = -1;
+       pid = waitpid(child, &status, WNOHANG);
+       T_ASSERT_EQ(pid, child, "waitpid returns correct pid");
+       T_EXPECT_EQ(WIFSIGNALED(status), true, "child was signaled"); 
+       T_EXPECT_EQ(WTERMSIG(status), SIGTERM, "child was sent SIGTERM");
+}
index eaf6745bb69368610753a85c002e68a1ce3d744e..aa081f3d8bd63d40e91a573769267f2d2b651a8e 100644 (file)
@@ -15,7 +15,7 @@
  * allocate at least this many GB of VA space. i.e. with the entitlement, n GB
  * must be allocatable; whereas without it, it must be less.
  */
-#define ALLOC_TEST_GB 12
+#define ALLOC_TEST_GB 54
 
 T_DECL(jumbo_va_spaces_28530648,
        "Verify that the \"dynamic-codesigning\" entitlement is required to utilize an extra-large "
diff --git a/tools/tests/darwintests/memorystatus_vm_map_fork.c b/tools/tests/darwintests/memorystatus_vm_map_fork.c
new file mode 100644 (file)
index 0000000..dc92e5c
--- /dev/null
@@ -0,0 +1,467 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+#include <spawn.h>
+#include <spawn_private.h>
+#include <stdint.h>
+#include <sys/sysctl.h>
+#include <sys/spawn_internal.h>
+#include <sys/kern_memorystatus.h>
+#include <mach-o/dyld.h>
+
+#include <darwintest.h>
+#include <darwintest_utils.h>
+
+T_GLOBAL_META(
+       T_META_NAMESPACE("xnu.vm"),
+       T_META_CHECK_LEAKS(false)
+);
+
+extern char **environ;
+
+/*
+ * This test file contains two sub-tests which attempt to verify
+ * the allowing or not allowing of a corpse for crashreporter when
+ * a task exceeds its memory allocation limit. vm_map_fork() is the
+ * kernel routine used to generate a corpse task.
+ *
+ * A corpse is allowed to be taken if a task's memory resource limit that
+ * is exceeded is less than 1/2 of the system wide task limit.
+ * If the amount exceeds 1/2 the sytem wide limit, then the corpse is disallowed.
+ *
+ * If the device under test is already under pressure, the test
+ * could fail due to jetsam cutting in and killing the parent, child or
+ * other necessary testing processes.
+ */
+
+/* Test variants */
+#define TEST_ALLOWED    0x1
+#define TEST_NOT_ALLOWED 0x2
+
+/*
+ * Values which the kernel OR's into the PID when a corpse
+ * is either allowed or disallowed for the
+ * kern.memorystatus_vm_map_fork_pidwatch sysctl.
+ */
+#define MEMORYSTATUS_VM_MAP_FORK_ALLOWED       0x100000000ul
+#define MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED 0x200000000ul
+
+/*
+ * The memory allocation happens in a child process, this
+ * is stuff to deal with creating and managing the child.
+ * The child will only execute the T_HELPER_DECL.
+ */
+static char testpath[PATH_MAX];
+static uint32_t testpath_size = sizeof(testpath);
+#define LIMIT_DELTA_MB 5 /* an arbitrary limit delta */
+#define MEGABYTE       (1024 * 1024)
+
+/*
+ * The child process communicates back to parent via an exit() code.
+ */
+enum child_exits {
+       NORMAL_EXIT = 0,
+       NO_MEMSIZE_ARG,
+       INVALID_MEMSIZE,
+       MALLOC_FAILED,
+       NUM_CHILD_EXIT
+};
+static char *child_exit_why[] = {
+       "normal exit",
+       "no memsize argument to child",
+       "invalid memsize argument to child",
+       "malloc() failed",
+};
+
+/*
+ * Corpse collection only happens in development kernels.
+ * So we need this to detect if the test is relevant.
+ */
+static boolean_t
+is_development_kernel(void)
+{
+       int ret;
+       int dev = 0;
+       size_t dev_size = sizeof(dev);
+
+       ret = sysctlbyname("kern.development", &dev, &dev_size, NULL, 0);
+       if (ret != 0) {
+               return FALSE;
+       }
+
+       return (dev != 0);
+}
+
+/*
+ * Set/Get the sysctl used to determine if corpse collection occurs.
+ * This is done by the kernel checking for a specific PID.
+ */
+static void
+set_memorystatus_vm_map_fork_pidwatch(pid_t pid)
+{
+       uint64_t new_value = (uint64_t)pid;
+       size_t new_len = sizeof(new_value);
+       int err;
+
+       err = sysctlbyname("kern.memorystatus_vm_map_fork_pidwatch", NULL, NULL, &new_value, new_len);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(err, "set sysctlbyname(kern.memorystatus_vm_map_fork_pidwatch...) failed");
+       return;
+}
+
+static uint64_t
+get_memorystatus_vm_map_fork_pidwatch()
+{
+       uint64_t value = 0;
+       size_t val_len = sizeof(value);
+       int err;
+
+       err = sysctlbyname("kern.memorystatus_vm_map_fork_pidwatch", &value, &val_len, NULL, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(err, "get sysctlbyname(kern.memorystatus_vm_map_fork_pidwatch...) failed");
+
+       return value;
+}
+
+/*
+ * We want to avoid jetsam giving us bad results, if possible. So check if there's
+ * enough memory for the test to run, waiting briefly for some to free up.
+ */
+static void
+wait_for_free_mem(int need_mb)
+{
+       int64_t         memsize;
+       int             memorystatus_level;
+       size_t          size;
+       int64_t         avail;
+       int             err;
+       int             try;
+
+       /*
+        * get amount of memory in the machine
+        */
+       size = sizeof(memsize);
+       err = sysctlbyname("hw.memsize", &memsize, &size, NULL, 0);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(err, "sysctlbyname(hw.memsize...) failed");
+
+       /*
+        * Use a loop to briefly sleep and recheck if short on memory.
+        */
+       try = 1;
+       for (;;) {
+
+               /*
+                * memorystatus_level is a percentage of memory available. For example 20 means 1/5 of memory.
+                * It currently doesn't exist on macOS but neither does jetsam, so pass the test there.
+                */
+               size = sizeof(memorystatus_level);
+               if (sysctlbyname("kern.memorystatus_level", &memorystatus_level, &size, NULL, 0) != 0)
+                       return;
+               T_QUIET; T_ASSERT_LE(memorystatus_level, 100, "memorystatus_level too high");
+               T_QUIET; T_ASSERT_GT(memorystatus_level, 0, "memorystatus_level negative");
+
+               /*
+                * jetsam kicks in at memory status level of 15%, so subtract that much out of what's available.
+                */
+               avail = MAX(0, (memsize * (memorystatus_level - 15)) / 100);
+
+               /*
+                * We're good to go if there's more than enough available.
+                */
+               if ((int64_t)need_mb * MEGABYTE < avail)
+                       return;
+
+               /*
+                * issue a message to log and sleep briefly to see if we can get more memory
+                */
+               if (try-- == 0)
+                       break;
+               T_LOG("Need %d MB, only %d MB available. sleeping 5 seconds for more to free. memorystatus_level %d",
+                   need_mb, (int)(avail / MEGABYTE), memorystatus_level);
+               sleep(5);
+       }
+       T_SKIP("Needed %d MB, but only %d MB available. Skipping test to avoid jetsam issues.",
+           need_mb, (int)(avail / MEGABYTE));
+}
+
+
+/*
+ * The main test calls this to spawn child process which will run and
+ * exceed some memory limit. The child is initially suspended so that
+ * we can do the sysctl calls before it runs.
+ * Since this is a libdarwintest, the "-n" names the T_HELPER_DECL() that
+ * we want to run. The arguments specific to the test follow a "--".
+ */
+static pid_t
+spawn_child_process(
+       char * const executable,
+       char * const memlimit,
+       short flags,
+       int priority,
+       int active_limit_mb,
+       int inactive_limit_mb)
+{
+       posix_spawnattr_t spawn_attrs;
+       int err;
+       pid_t child_pid;
+       char * const argv_child[] = { executable, "-n", "child_process", "--", memlimit, NULL };
+
+       err = posix_spawnattr_init(&spawn_attrs);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(err, "  posix_spawnattr_init() failed");
+
+       err = posix_spawnattr_setflags(&spawn_attrs, POSIX_SPAWN_START_SUSPENDED);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(err, "  posix_spawnattr_setflags() failed");
+
+       err = posix_spawnattr_setjetsam_ext(&spawn_attrs, flags, priority, active_limit_mb, inactive_limit_mb);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(err, "  posix_spawnattr_setjetsam_ext() failed");
+
+       err = posix_spawn(&child_pid, executable, NULL, &spawn_attrs, argv_child, environ);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(err, "  posix_spawn() failed");
+
+       return child_pid;
+}
+
+
+/*
+ * The parent calls this to continue the suspended child, then wait for its result.
+ * We collect its resource usage to vefiry the expected amount allocated.
+ */
+static void
+test_child_process(pid_t child_pid, int *status, struct rusage *ru)
+{
+       int err = 0;
+       pid_t got_pid;
+
+       T_LOG("  continuing child[%d]\n", child_pid);
+
+       err = kill(child_pid, SIGCONT);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(err, "  kill(%d, SIGCONT) failed", child_pid);
+
+       T_LOG("  waiting for child[%d] to exit", child_pid);
+
+       got_pid = wait4(child_pid, status, 0, ru);
+       T_QUIET; T_ASSERT_EQ(child_pid, got_pid, "  wait4(%d, ...) returned %d", child_pid, got_pid);
+}
+
+/*
+ * The child process executes this code. The easiest way, with given darwintest infrastructure,
+ * it has to return information is via exit status.
+ */
+T_HELPER_DECL(child_process, "child allocates memory to failure")
+{
+#define BYTESPERALLOC  MEGABYTE
+#define BYTESINEXCESS  (2 * MEGABYTE) /* 2 MB - arbitrary */
+       char *limit;
+       long limit_mb = 0;
+       long max_bytes_to_munch, bytes_remaining, bytes_this_munch;
+       void *mem = NULL;
+
+       /*
+        * This helper is run in a child process. The helper sees one argument
+        * as a string which is the amount of memory in megabytes to allocate.
+        */
+       if (argc != 1)
+               exit(NO_MEMSIZE_ARG);
+
+       limit = argv[0];
+       errno = 0;
+       limit_mb = strtol(limit, NULL, 10);
+       if (errno != 0 || limit_mb <= 0)
+               exit(INVALID_MEMSIZE);
+
+       /* Compute in excess of assigned limit */
+       max_bytes_to_munch = limit_mb * MEGABYTE;
+       max_bytes_to_munch += BYTESINEXCESS;
+
+       for (bytes_remaining = max_bytes_to_munch; bytes_remaining > 0; bytes_remaining -= bytes_this_munch) {
+               bytes_this_munch = MIN(bytes_remaining, BYTESPERALLOC);
+
+               mem = malloc((size_t)bytes_this_munch);
+               if (mem == NULL)
+                       exit(MALLOC_FAILED);
+               arc4random_buf(mem, (size_t)bytes_this_munch);
+       }
+
+       /* We chewed up all the memory we were asked to. */
+       exit(NORMAL_EXIT);
+}
+
+
+/*
+ * Actual test body.
+ */
+static void
+memorystatus_vm_map_fork_parent(int test_variant)
+{
+       int             max_task_pmem = 0; /* MB */
+       size_t          size = 0;
+       int             active_limit_mb = 0;
+       int             inactive_limit_mb = 0;
+       short           flags = 0;
+       char            memlimit_str[16];
+       pid_t           child_pid;
+       int             child_status;
+       uint64_t        kernel_pidwatch_val;
+       uint64_t        expected_pidwatch_val;
+       int             ret;
+       struct rusage   ru;
+       enum child_exits exit_val;
+
+       /*
+        * The code to set/get the pidwatch sysctl is only in
+        * development kernels. Skip the test if not on one.
+        */
+       if (!is_development_kernel()) {
+               T_SKIP("Can't test on release kernel");
+       }
+
+       /*
+        * Determine a memory limit based on system having one or not.
+        */
+       size = sizeof(max_task_pmem);
+       (void)sysctlbyname("kern.max_task_pmem", &max_task_pmem, &size, NULL, 0);
+       if (max_task_pmem <= 0)
+               max_task_pmem = 0;
+
+       if (test_variant == TEST_ALLOWED) {
+               
+               /*
+                * Tell the child to allocate less than 1/2 the system wide limit.
+                */
+               if (max_task_pmem / 2 - LIMIT_DELTA_MB <= 0) {
+                       active_limit_mb = LIMIT_DELTA_MB;
+               } else {
+                       active_limit_mb = max_task_pmem / 2 - LIMIT_DELTA_MB;
+               }
+               expected_pidwatch_val = MEMORYSTATUS_VM_MAP_FORK_ALLOWED;
+
+       } else { /* TEST_NOT_ALLOWED */
+
+               /*
+                * Tell the child to allocate more than 1/2 the system wide limit.
+                */
+               active_limit_mb = (max_task_pmem / 2) + LIMIT_DELTA_MB;
+               if (max_task_pmem == 0) {
+                       expected_pidwatch_val = MEMORYSTATUS_VM_MAP_FORK_ALLOWED;
+               } else {
+                       expected_pidwatch_val = MEMORYSTATUS_VM_MAP_FORK_NOT_ALLOWED;
+               }
+
+       }
+       inactive_limit_mb = active_limit_mb;
+       T_LOG("using limit of %d Meg", active_limit_mb);
+
+       /*
+        * When run as part of a larger suite, a previous test
+        * may have left the system temporarily with too little
+        * memory to run this test. We try to detect if there is
+        * enough free memory to proceed, waiting a little bit
+        * for memory to free up.
+        */
+       wait_for_free_mem(active_limit_mb);
+
+#if defined(__x86_64__)
+       /*
+        * vm_map_fork() is always allowed on desktop.
+        */
+       expected_pidwatch_val = MEMORYSTATUS_VM_MAP_FORK_ALLOWED;
+#endif
+
+       /*
+        * Prepare the arguments needed to spawn the child process.
+        */
+       memset (memlimit_str, 0, sizeof(memlimit_str));
+       (void)sprintf(memlimit_str, "%d", active_limit_mb);
+
+       ret = _NSGetExecutablePath(testpath, &testpath_size);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "_NSGetExecutablePath(%s, ...)", testpath);
+
+       /*
+        * We put the child process in FOREGROUND to try and keep jetsam's hands off it.
+        */
+       child_pid = spawn_child_process(testpath, memlimit_str, flags,
+           JETSAM_PRIORITY_FOREGROUND, active_limit_mb, inactive_limit_mb);
+
+       expected_pidwatch_val |= (uint64_t)child_pid;
+
+       /*
+        * We only reach here if parent successfully spawned child process.
+        */
+       T_LOG("  spawned child_pid[%d] with memlimit %s (%d)MB\n",
+           child_pid, memlimit_str, active_limit_mb);
+
+       /*
+        * Set the kernel's pidwatch to look for the child.
+        */
+       (void)set_memorystatus_vm_map_fork_pidwatch((pid_t)0);
+       (void)set_memorystatus_vm_map_fork_pidwatch(child_pid);
+
+       /*
+        * Let the child run and wait for it to finish.
+        */
+       test_child_process(child_pid, &child_status, &ru);
+       T_LOG("Child exited with max_rss of %ld", ru.ru_maxrss);
+
+       /*
+        * Retrieve the kernel's pidwatch value. This should now indicate
+        * if the corpse was allowed or not.
+        */
+       kernel_pidwatch_val = get_memorystatus_vm_map_fork_pidwatch();
+       (void)set_memorystatus_vm_map_fork_pidwatch((pid_t)0);
+
+       /*
+        * If the child died abnormally, the test is invalid.
+        */
+       if (!WIFEXITED(child_status)) {
+               if (WIFSIGNALED(child_status)) {
+                       /* jetsam kills a process with SIGKILL */
+                       if (WTERMSIG(child_status) == SIGKILL)
+                               T_LOG("Child appears to have been a jetsam victim");
+                       T_SKIP("Child terminated by signal %d test result invalid", WTERMSIG(child_status));
+               }
+               T_SKIP("child did not exit normally (status=%d) test result invalid", child_status);
+       }
+
+       /*
+        * We don't expect the child to exit for any other reason than success
+        */
+       exit_val = (enum child_exits)WEXITSTATUS(child_status);
+       T_QUIET; T_ASSERT_EQ(exit_val, NORMAL_EXIT, "child exit due to: %s", 
+           (0 < exit_val && exit_val < NUM_CHILD_EXIT) ? child_exit_why[exit_val] : "unknown");
+
+       /*
+        * If the kernel aborted generating a corpse for other reasons, the test is invalid.
+        */
+       if (kernel_pidwatch_val == -1ull) {
+               T_SKIP("corpse generation was aborted by kernel");
+       }
+
+       /*
+        * We should always have made it through the vm_map_fork() checks in the kernel for this test.
+        */
+       T_QUIET; T_ASSERT_NE_ULLONG(kernel_pidwatch_val, (uint64_t)child_pid, "child didn't trigger corpse generation");
+
+       T_EXPECT_EQ(kernel_pidwatch_val, expected_pidwatch_val, "kernel value 0x%llx - expected 0x%llx",
+           kernel_pidwatch_val, expected_pidwatch_val);
+}
+
+/*
+ * The order of these 2 test functions is important. They will be executed by the test framwork in order.
+ *
+ * We test "not allowed first", then "allowed". If it were the other way around, the corpse from the "allowed"
+ * test would likely cause memory pressure and jetsam would likely kill the "not allowed" test.
+ */
+T_DECL(memorystatus_vm_map_fork_test_not_allowed, "test that corpse generation was not allowed")
+{
+       memorystatus_vm_map_fork_parent(TEST_NOT_ALLOWED);
+}
+
+T_DECL(memorystatus_vm_map_fork_test_allowed, "test corpse generation allowed")
+{
+
+       memorystatus_vm_map_fork_parent(TEST_ALLOWED);
+}
index 1d0223a1591d21993b4cbac943af2ae002a890b8..f652725bb30a9574773c659d56eb19342a22387f 100644 (file)
@@ -2,6 +2,7 @@
 #include <mach/mach_vm.h>
 #include <mach/mach_port.h>
 #include <mach/mach_host.h>
+#include <mach/mach_error.h>
 #include <mach-o/dyld.h>
 #include <sys/sysctl.h>
 #include <sys/kdebug.h>
@@ -21,25 +22,29 @@ T_GLOBAL_META(
        T_META_CHECK_LEAKS(false)
 );
 
-#define TIMEOUT_SECS                1500
+#define TIMEOUT_SECS                                   1500
 
 #if TARGET_OS_EMBEDDED
-#define ALLOCATION_SIZE_VM_REGION      (16*1024)               /* 16 KB */
-#define ALLOCATION_SIZE_VM_OBJECT      ALLOCATION_SIZE_VM_REGION
+#define ALLOCATION_SIZE_VM_REGION                              (16*1024)               /* 16 KB */
+#define ALLOCATION_SIZE_VM_OBJECT                              ALLOCATION_SIZE_VM_REGION
 #else
-#define ALLOCATION_SIZE_VM_REGION      (1024*1024*100) /* 100 MB */
-#define ALLOCATION_SIZE_VM_OBJECT      (16*1024)               /* 16 KB */
+#define ALLOCATION_SIZE_VM_REGION                              (1024*1024*100) /* 100 MB */
+#define ALLOCATION_SIZE_VM_OBJECT                              (16*1024)               /* 16 KB */
 #endif
-#define MAX_CHILD_PROCS             100
+#define MAX_CHILD_PROCS                                100
 
-#define ZONEMAP_JETSAM_LIMIT_SYSCTL "kern.zone_map_jetsam_limit=60"
+#define ZONEMAP_JETSAM_LIMIT_SYSCTL                    "kern.zone_map_jetsam_limit=60"
 
-#define VME_ZONE_TEST_OPT           "allocate_vm_regions"
-#define VM_OBJECTS_ZONE_TEST_OPT    "allocate_vm_objects"
-#define GENERIC_ZONE_TEST_OPT       "allocate_from_generic_zone"
+#define VME_ZONE_TEST_OPT                              "allocate_vm_regions"
+#define VM_OBJECTS_ZONE_TEST_OPT                       "allocate_vm_objects"
+#define GENERIC_ZONE_TEST_OPT                          "allocate_from_generic_zone"
 
-#define VM_TAG1                100
-#define VM_TAG2                101
+#define VME_ZONE                                                               "VM map entries"
+#define VMOBJECTS_ZONE                                                 "vm objects"
+#define VMENTRY_TO_VMOBJECT_COMPARISON_RATIO   98
+
+#define VM_TAG1                                                                        100
+#define VM_TAG2                                                                        101
 
 enum {
     VME_ZONE_TEST = 0,
@@ -47,13 +52,26 @@ enum {
     GENERIC_ZONE_TEST,
 };
 
-static int current_test_index = 0;
+typedef struct test_config_struct {
+       int test_index;
+       int num_zones;
+       const char *helper_func;
+       mach_zone_name_array_t zone_names;
+} test_config_struct;
+
+static test_config_struct current_test;
 static int num_children = 0;
 static bool test_ending = false;
-static bool within_dispatch_source_handler = false;
+static bool within_dispatch_signal_handler = false;
+static bool within_dispatch_timer_handler = false;
 static dispatch_source_t ds_signal = NULL;
+static dispatch_source_t ds_timer = NULL;
 static ktrace_session_t session = NULL;
 
+static mach_zone_info_array_t zone_info_array = NULL;
+static mach_zone_name_t largest_zone_name;
+static mach_zone_info_t largest_zone_info;
+
 static char testpath[PATH_MAX];
 static pid_t child_pids[MAX_CHILD_PROCS];
 static pthread_mutex_t test_ending_mtx;
@@ -64,9 +82,19 @@ static void allocate_from_generic_zone(void);
 static void cleanup_and_end_test(void);
 static void setup_ktrace_session(void);
 static void spawn_child_process(void);
-static void run_test_for_zone(int index);
+static void run_test(void);
+static bool verify_generic_jetsam_criteria(void);
+static bool vme_zone_compares_to_vm_objects(void);
+static void print_zone_map_size(void);
+static void query_zone_info(void);
+static void print_zone_info(mach_zone_name_t *zn, mach_zone_info_t *zi);
 
 extern void mach_zone_force_gc(host_t host);
+extern kern_return_t mach_zone_info_for_largest_zone(
+       host_priv_t host,
+       mach_zone_name_t *name,
+       mach_zone_info_t *info
+);
 
 static void allocate_vm_regions(void)
 {
@@ -144,6 +172,76 @@ static void allocate_from_generic_zone(void)
        }
 }
 
+static void print_zone_info(mach_zone_name_t *zn, mach_zone_info_t *zi)
+{
+       T_LOG("ZONE NAME: %-35sSIZE: %-25lluELEMENTS: %llu",
+                       zn->mzn_name, zi->mzi_cur_size, zi->mzi_count);
+}
+
+static void query_zone_info(void)
+{
+       int i;
+       kern_return_t kr;
+       static uint64_t num_calls = 0;
+
+       for (i = 0; i < current_test.num_zones; i++) {
+               kr = mach_zone_info_for_zone(mach_host_self(), current_test.zone_names[i], &(zone_info_array[i]));
+               T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_zone_info_for_zone(%s) returned %d [%s]", current_test.zone_names[i].mzn_name, kr, mach_error_string(kr));
+       }
+       kr = mach_zone_info_for_largest_zone(mach_host_self(), &largest_zone_name, &largest_zone_info);
+       T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_zone_info_for_largest_zone returned %d [%s]", kr, mach_error_string(kr));
+
+       num_calls++;
+       if (num_calls % 10 != 0) {
+               return;
+       }
+
+       /* Print out size and element count for zones relevant to the test */
+       for (i = 0; i < current_test.num_zones; i++) {
+               print_zone_info(&(current_test.zone_names[i]), &(zone_info_array[i]));
+       }
+}
+
+static bool vme_zone_compares_to_vm_objects(void)
+{
+       int i;
+       uint64_t vm_object_element_count = 0, vm_map_entry_element_count = 0;
+
+       T_LOG("Comparing element counts of \"VM map entries\" and \"vm objects\" zones");
+       for (i = 0; i < current_test.num_zones; i++) {
+               if (!strcmp(current_test.zone_names[i].mzn_name, VME_ZONE)) {
+                       vm_map_entry_element_count = zone_info_array[i].mzi_count;
+               } else if (!strcmp(current_test.zone_names[i].mzn_name, VMOBJECTS_ZONE)) {
+                       vm_object_element_count = zone_info_array[i].mzi_count;
+               }
+               print_zone_info(&(current_test.zone_names[i]), &(zone_info_array[i]));
+       }
+
+       T_LOG("# VM map entries as percentage of # vm objects = %llu", (vm_map_entry_element_count * 100)/ vm_object_element_count);
+       if (vm_map_entry_element_count >= ((vm_object_element_count * VMENTRY_TO_VMOBJECT_COMPARISON_RATIO) / 100)) {
+               T_LOG("Number of VM map entries is comparable to vm objects\n\n");
+               return true;
+       }
+       T_LOG("Number of VM map entries is NOT comparable to vm objects\n\n");
+       return false;
+}
+
+static bool verify_generic_jetsam_criteria(void)
+{
+       T_LOG("Largest zone info");
+       print_zone_info(&largest_zone_name, &largest_zone_info);
+
+       /* If VM map entries is not the largest zone */
+       if (strcmp(largest_zone_name.mzn_name, VME_ZONE)) {
+               /* If vm objects is the largest zone and the VM map entries zone had comparable # of elements, return false */
+               if (!strcmp(largest_zone_name.mzn_name, VMOBJECTS_ZONE) && vme_zone_compares_to_vm_objects()) {
+                       return false;
+               }
+               return true;
+       }
+       return false;
+}
+
 static void cleanup_and_end_test(void)
 {
        int i;
@@ -163,8 +261,13 @@ static void cleanup_and_end_test(void)
        T_LOG("Number of processes spawned: %d", num_children);
        T_LOG("Cleaning up...");
 
+       /* Disable the timer that queries and prints zone info periodically */
+       if (ds_timer != NULL && !within_dispatch_timer_handler) {
+               dispatch_source_cancel(ds_timer);
+       }
+
        /* Disable signal handler that spawns child processes, only if we're not in the event handler's context */
-       if (ds_signal != NULL && !within_dispatch_source_handler) {
+       if (ds_signal != NULL && !within_dispatch_signal_handler) {
                dispatch_source_cancel_and_wait(ds_signal);
        }
 
@@ -187,6 +290,10 @@ static void cleanup_and_end_test(void)
        if (session != NULL) {
                ktrace_end(session, 1);
        }
+
+       for (i = 0; i < current_test.num_zones; i++) {
+               print_zone_info(&(current_test.zone_names[i]), &(zone_info_array[i]));
+       }
 }
 
 static void setup_ktrace_session(void)
@@ -197,6 +304,8 @@ static void setup_ktrace_session(void)
        session = ktrace_session_create();
        T_QUIET; T_ASSERT_NOTNULL(session, "ktrace_session_create");
 
+       ktrace_set_interactive(session);
+
        ktrace_set_completion_handler(session, ^{
                ktrace_session_destroy(session);
                T_END;
@@ -209,11 +318,17 @@ static void setup_ktrace_session(void)
 
                /* We don't care about jetsams for any other reason except zone-map-exhaustion */
                if (event->arg2 == kMemorystatusKilledZoneMapExhaustion) {
-                       T_LOG("[memorystatus_do_kill] jetsam reason: zone-map-exhaustion, pid: %lu", event->arg1);
-                       if (current_test_index == VME_ZONE_TEST || current_test_index == VM_OBJECTS_ZONE_TEST) {
+                       cleanup_and_end_test();
+                       T_LOG("[memorystatus_do_kill] jetsam reason: zone-map-exhaustion, pid: %lu\n\n", event->arg1);
+                       if (current_test.test_index == VME_ZONE_TEST || current_test.test_index == VM_OBJECTS_ZONE_TEST) {
                                /*
                                 * For the VM map entries zone we try to kill the leaking process.
                                 * Verify that we jetsammed one of the processes we spawned.
+                                *
+                                * For the vm objects zone we pick the leaking process via the VM map entries
+                                * zone, if the number of vm objects and VM map entries are comparable.
+                                * The test simulates this scenario, we should see a targeted jetsam for the
+                                * vm objects zone too.
                                 */
                                for (i = 0; i < num_children; i++) {
                                        if (child_pids[i] == (pid_t)event->arg1) {
@@ -221,12 +336,18 @@ static void setup_ktrace_session(void)
                                                break;
                                        }
                                }
+                               /*
+                                * If we didn't see a targeted jetsam, verify that the largest zone actually
+                                * fulfilled the criteria for generic jetsams.
+                                */
+                               if (!received_jetsam_event && verify_generic_jetsam_criteria()) {
+                                       received_jetsam_event = true;
+                               }
                        } else {
                                received_jetsam_event = true;
                        }
 
-                       T_ASSERT_TRUE(received_jetsam_event, "Received jetsam event as expected");
-                       cleanup_and_end_test();
+                       T_ASSERT_TRUE(received_jetsam_event, "Received zone-map-exhaustion jetsam event as expected");
                }
        });
        T_QUIET; T_ASSERT_POSIX_ZERO(ret, "ktrace_events_single");
@@ -235,26 +356,32 @@ static void setup_ktrace_session(void)
        T_QUIET; T_ASSERT_POSIX_ZERO(ret, "ktrace_start");
 }
 
+static void print_zone_map_size(void)
+{
+       int ret;
+       uint64_t zstats[2];
+       size_t zstats_size = sizeof(zstats);
+
+       ret = sysctlbyname("kern.zone_map_size_and_capacity", &zstats, &zstats_size, NULL, 0);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.zone_map_size_and_capacity failed");
+
+       T_LOG("Zone map capacity: %-30lldZone map size: %lld [%lld%% full]", zstats[1], zstats[0], (zstats[0] * 100)/zstats[1]);
+}
+
 static void spawn_child_process(void)
 {
        pid_t pid = -1;
+       char helper_func[50];
        char *launch_tool_args[4];
-       within_dispatch_source_handler = true;
 
        T_QUIET; T_ASSERT_LT(num_children, MAX_CHILD_PROCS, "Spawned %d children. Timing out...", MAX_CHILD_PROCS);
 
+       strlcpy(helper_func, current_test.helper_func, sizeof(helper_func));
        launch_tool_args[0] = testpath;
        launch_tool_args[1] = "-n";
+       launch_tool_args[2] = helper_func;
        launch_tool_args[3] = NULL;
 
-       if (current_test_index == VME_ZONE_TEST) {
-               launch_tool_args[2] = VME_ZONE_TEST_OPT;
-       } else if (current_test_index == VM_OBJECTS_ZONE_TEST) {
-               launch_tool_args[2] = VM_OBJECTS_ZONE_TEST_OPT;
-       } else if (current_test_index == GENERIC_ZONE_TEST) {
-               launch_tool_args[2] = GENERIC_ZONE_TEST_OPT;
-       }
-
        /* Spawn the child process */
        int rc = dt_launch_tool(&pid, launch_tool_args, false, NULL, NULL);
        if (rc != 0) {
@@ -263,30 +390,50 @@ static void spawn_child_process(void)
        T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "dt_launch_tool");
 
        child_pids[num_children++] = pid;
-       within_dispatch_source_handler = false;
 }
 
-static void run_test_for_zone(int index)
+static void run_test(void)
 {
-       int ret, dev;
-       size_t dev_size = sizeof(dev);
-       uint32_t testpath_buf_size = sizeof(testpath);
+       uint64_t mem;
+       uint32_t testpath_buf_size, pages;
+       int ret, dev, pgsz;
+       size_t sysctl_size;
 
        T_ATEND(cleanup_and_end_test);
        T_SETUPBEGIN;
 
-       current_test_index = index;
-
-       ret = sysctlbyname("kern.development", &dev, &dev_size, NULL, 0);
+       dev = 0;
+       sysctl_size = sizeof(dev);
+       ret = sysctlbyname("kern.development", &dev, &sysctl_size, NULL, 0);
        T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.development failed");
        if (dev == 0) {
                T_SKIP("Skipping test on release kernel");
        }
 
+       testpath_buf_size = sizeof(testpath);
        ret = _NSGetExecutablePath(testpath, &testpath_buf_size);
        T_QUIET; T_ASSERT_POSIX_ZERO(ret, "_NSGetExecutablePath");
        T_LOG("Executable path: %s", testpath);
 
+       sysctl_size = sizeof(mem);
+       ret = sysctlbyname("hw.memsize", &mem, &sysctl_size, NULL, 0);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl hw.memsize failed");
+       T_LOG("hw.memsize: %llu", mem);
+
+       sysctl_size = sizeof(pgsz);
+       ret = sysctlbyname("vm.pagesize", &pgsz, &sysctl_size, NULL, 0);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl vm.pagesize failed");
+       T_LOG("vm.pagesize: %d", pgsz);
+
+       sysctl_size = sizeof(pages);
+       ret = sysctlbyname("vm.pages", &pages, &sysctl_size, NULL, 0);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl vm.pages failed");
+       T_LOG("vm.pages: %d", pages);
+
+       zone_info_array = (mach_zone_info_array_t) calloc((unsigned long)current_test.num_zones, sizeof *zone_info_array);
+
+       print_zone_map_size();
+
        /*
         * If the timeout specified by T_META_TIMEOUT is hit, the atend handler does not get called.
         * So we're queueing a dispatch block to fire after TIMEOUT_SECS seconds, so we can exit cleanly.
@@ -302,15 +449,31 @@ static void run_test_for_zone(int index)
         */
        signal(SIGUSR1, SIG_IGN);
        ds_signal = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGUSR1, 0, dispatch_get_main_queue());
-       T_QUIET; T_ASSERT_NOTNULL(ds_signal, "dispatch_source_create");
+       T_QUIET; T_ASSERT_NOTNULL(ds_signal, "dispatch_source_create: signal");
 
        dispatch_source_set_event_handler(ds_signal, ^{
+               within_dispatch_signal_handler = true;
+               print_zone_map_size();
+
                /* Wait a few seconds before spawning another child. Keeps us from allocating too aggressively */
                sleep(5);
                spawn_child_process();
+               within_dispatch_signal_handler = false;
        });
        dispatch_activate(ds_signal);
 
+       /* Timer to query jetsam-relevant zone info every second. Print it every 10 seconds. */
+       ds_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_queue_create("timer_queue", NULL));
+       T_QUIET; T_ASSERT_NOTNULL(ds_timer, "dispatch_source_create: timer");
+    dispatch_source_set_timer(ds_timer, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC), NSEC_PER_SEC, 0);
+
+       dispatch_source_set_event_handler(ds_timer, ^{
+               within_dispatch_timer_handler = true;
+               query_zone_info();
+               within_dispatch_timer_handler = false;
+    });
+       dispatch_activate(ds_timer);
+
        /* Set up a ktrace session to listen for jetsam events */
        setup_ktrace_session();
 
@@ -323,17 +486,7 @@ static void run_test_for_zone(int index)
        dispatch_main();
 }
 
-T_HELPER_DECL(allocate_vm_regions, "allocates VM regions")
-{
-       allocate_vm_regions();
-}
-
-T_HELPER_DECL(allocate_vm_objects, "allocates VM objects and VM regions")
-{
-       allocate_vm_objects();
-}
-
-T_HELPER_DECL(allocate_from_generic_zone, "allocates from a generic zone")
+static void move_to_idle_band(void)
 {
        memorystatus_priority_properties_t props;
 
@@ -341,6 +494,8 @@ T_HELPER_DECL(allocate_from_generic_zone, "allocates from a generic zone")
         * We want to move the processes we spawn into the idle band, so that jetsam can target them first.
         * This prevents other important BATS tasks from getting killed, specially in LTE where we have very few
         * processes running.
+        *
+        * This is only needed for tests which (are likely to) lead us down the generic jetsam path.
         */
        props.priority = JETSAM_PRIORITY_IDLE;
        props.user_data = 0;
@@ -349,7 +504,22 @@ T_HELPER_DECL(allocate_from_generic_zone, "allocates from a generic zone")
                printf("memorystatus call to change jetsam priority failed\n");
                exit(-1);
        }
+}
+
+T_HELPER_DECL(allocate_vm_regions, "allocates VM regions")
+{
+       allocate_vm_regions();
+}
+
+T_HELPER_DECL(allocate_vm_objects, "allocates VM objects and VM regions")
+{
+       move_to_idle_band();
+       allocate_vm_objects();
+}
 
+T_HELPER_DECL(allocate_from_generic_zone, "allocates from a generic zone")
+{
+       move_to_idle_band();
        allocate_from_generic_zone();
 }
 
@@ -367,7 +537,15 @@ T_DECL(    memorystatus_vme_zone_test,
  */
                T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL))
 {
-       run_test_for_zone(VME_ZONE_TEST);
+       current_test = (test_config_struct) {
+               .test_index = VME_ZONE_TEST,
+               .helper_func = VME_ZONE_TEST_OPT,
+               .num_zones = 1,
+               .zone_names = (mach_zone_name_t []){
+                       { .mzn_name = VME_ZONE }
+               }
+       };
+       run_test();
 }
 
 T_DECL(        memorystatus_vm_objects_zone_test,
@@ -378,7 +556,16 @@ T_DECL(    memorystatus_vm_objects_zone_test,
  */
                T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL))
 {
-       run_test_for_zone(VM_OBJECTS_ZONE_TEST);
+       current_test = (test_config_struct) {
+               .test_index = VM_OBJECTS_ZONE_TEST,
+               .helper_func = VM_OBJECTS_ZONE_TEST_OPT,
+               .num_zones = 2,
+               .zone_names = (mach_zone_name_t []){
+                       { .mzn_name = VME_ZONE },
+                       { .mzn_name = VMOBJECTS_ZONE}
+               }
+       };
+       run_test();
 }
 
 T_DECL(        memorystatus_generic_zone_test,
@@ -389,5 +576,11 @@ T_DECL(    memorystatus_generic_zone_test,
  */
                T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL))
 {
-       run_test_for_zone(GENERIC_ZONE_TEST);
+       current_test = (test_config_struct) {
+               .test_index = GENERIC_ZONE_TEST,
+               .helper_func = GENERIC_ZONE_TEST_OPT,
+               .num_zones = 0,
+               .zone_names = NULL
+       };
+       run_test();
 }
diff --git a/tools/tests/darwintests/net_tun_pr_35136664.c b/tools/tests/darwintests/net_tun_pr_35136664.c
new file mode 100644 (file)
index 0000000..366f066
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/kern_control.h>
+#include <sys/sys_domain.h>
+
+#include <net/if_utun.h>
+#include <net/if_ipsec.h>
+
+#include <darwintest.h>
+#include <darwintest_utils.h>
+
+T_GLOBAL_META(T_META_NAMESPACE("xnu.net"));
+
+T_DECL(PR_35136664_utun,
+       "This bind a utun and close it without connecting")
+{
+       int tunsock;
+       struct ctl_info kernctl_info;
+       struct sockaddr_ctl kernctl_addr;
+
+       T_ASSERT_POSIX_SUCCESS(tunsock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), NULL);
+
+       memset(&kernctl_info, 0, sizeof(kernctl_info));
+       strlcpy(kernctl_info.ctl_name, UTUN_CONTROL_NAME, sizeof(kernctl_info.ctl_name));
+       T_ASSERT_POSIX_ZERO(ioctl(tunsock, CTLIOCGINFO, &kernctl_info), NULL);
+
+       memset(&kernctl_addr, 0, sizeof(kernctl_addr));
+       kernctl_addr.sc_len = sizeof(kernctl_addr);
+       kernctl_addr.sc_family = AF_SYSTEM;
+       kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
+       kernctl_addr.sc_id = kernctl_info.ctl_id;
+       kernctl_addr.sc_unit = 0;
+
+       T_ASSERT_POSIX_ZERO(bind(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
+
+       T_ASSERT_POSIX_ZERO(close(tunsock), NULL);
+}
+
+T_DECL(PR_35136664_ipsec,
+       "This bind a ipsec and close it without connecting")
+{
+       int tunsock;
+       struct ctl_info kernctl_info;
+       struct sockaddr_ctl kernctl_addr;
+
+       T_ASSERT_POSIX_SUCCESS(tunsock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), NULL);
+
+       memset(&kernctl_info, 0, sizeof(kernctl_info));
+       strlcpy(kernctl_info.ctl_name, IPSEC_CONTROL_NAME, sizeof(kernctl_info.ctl_name));
+       T_ASSERT_POSIX_ZERO(ioctl(tunsock, CTLIOCGINFO, &kernctl_info), NULL);
+
+       memset(&kernctl_addr, 0, sizeof(kernctl_addr));
+       kernctl_addr.sc_len = sizeof(kernctl_addr);
+       kernctl_addr.sc_family = AF_SYSTEM;
+       kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
+       kernctl_addr.sc_id = kernctl_info.ctl_id;
+       kernctl_addr.sc_unit = 0;
+
+       T_ASSERT_POSIX_ZERO(bind(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
+
+       T_ASSERT_POSIX_ZERO(close(tunsock), NULL);
+}
diff --git a/tools/tests/darwintests/net_tuntests.c b/tools/tests/darwintests/net_tuntests.c
new file mode 100644 (file)
index 0000000..6b5fd97
--- /dev/null
@@ -0,0 +1,544 @@
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+#include <poll.h>
+#include <sys/event.h>
+#include <uuid/uuid.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/kern_control.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/kern_control.h>
+#include <sys/sys_domain.h>
+
+#include <net/if.h>
+#include <net/if_ipsec.h>
+#include <net/if_utun.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <net/pfkeyv2.h>
+#include <netinet6/ipsec.h>
+
+#include <darwintest.h>
+#include <darwintest_utils.h>
+
+#include <skywalk/os_skywalk_private.h> // for SK_FEATURE_*
+
+T_GLOBAL_META(T_META_NAMESPACE("xnu.net.tun"));
+
+#if 0
+static void
+log_hexdump(const void *inp, size_t len)
+{
+       unsigned i, off = 0;
+       char buf[9+16*3+1];
+       for (i = 0; i < len; i++) {
+               if (i % 16 == 0)
+                       off = (unsigned)snprintf(buf, sizeof(buf), "%08x:", i);
+               off += (unsigned)snprintf(buf+off, sizeof(buf)-off, " %02x", (((const uint8_t *)inp)[i]) & 0xff);
+               if (i % 16 == 15)
+                       T_LOG("%s", buf);
+               }
+               if (len % 16)
+                       T_LOG("%s", buf);
+}
+#endif
+
+static uint64_t
+get_skywalk_features(void)
+{
+       uint64_t features = 0;
+       size_t len = sizeof(features);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(sysctlbyname("kern.skywalk.features", &features, &len, NULL, 0), NULL);
+       T_QUIET; T_ASSERT_EQ(len, sizeof(features), NULL);
+       T_QUIET; T_ASSERT_TRUE(features & SK_FEATURE_SKYWALK, NULL);
+       return features;
+}
+
+static bool g_is_ipsec_test;
+static bool g_is_utun_test;
+static int g_OPT_ENABLE_NETIF = -1;
+static int g_OPT_ENABLE_FLOWSWITCH = -1;
+static int g_OPT_ENABLE_CHANNEL = -1;
+static int g_OPT_GET_CHANNEL_UUID = -1;
+static int g_OPT_IFNAME = -1;
+static char *g_CONTROL_NAME = NULL;
+
+static void
+setup_ipsec_test(void)
+{
+       T_LOG("Configuring for ipsec tests");
+       g_OPT_ENABLE_NETIF = IPSEC_OPT_ENABLE_NETIF;
+       g_OPT_ENABLE_FLOWSWITCH = IPSEC_OPT_ENABLE_FLOWSWITCH;
+       g_OPT_ENABLE_CHANNEL = IPSEC_OPT_ENABLE_CHANNEL;
+       g_OPT_GET_CHANNEL_UUID = IPSEC_OPT_GET_CHANNEL_UUID;
+       g_OPT_IFNAME = IPSEC_OPT_IFNAME;
+       g_CONTROL_NAME = IPSEC_CONTROL_NAME;
+       g_is_ipsec_test = true;
+}
+
+static void
+setup_utun_test(void)
+{
+       T_LOG("Configuring for utun tests");
+       g_OPT_ENABLE_NETIF = UTUN_OPT_ENABLE_NETIF;
+       g_OPT_ENABLE_FLOWSWITCH = UTUN_OPT_ENABLE_FLOWSWITCH;
+       g_OPT_ENABLE_CHANNEL = UTUN_OPT_ENABLE_CHANNEL;
+       g_OPT_GET_CHANNEL_UUID = UTUN_OPT_GET_CHANNEL_UUID;
+       g_OPT_IFNAME = UTUN_OPT_IFNAME;
+       g_CONTROL_NAME = UTUN_CONTROL_NAME;
+       g_is_utun_test = true;
+}
+
+static void
+check_enables(int tunsock, int enable_netif, int enable_flowswitch, int enable_channel, uuid_t uuid)
+{
+       int scratch;
+       socklen_t scratchlen, uuidlen;
+       uuid_t scratchuuid;
+       if (!uuid) {
+               uuid = scratchuuid;
+       }
+
+       //T_LOG("checking tunsock %d", tunsock);
+
+       scratchlen = sizeof(scratch);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
+                       &scratch, &scratchlen), NULL);
+       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )scratchlen, sizeof(scratch), NULL);
+       T_QUIET; T_EXPECT_EQ(scratch, enable_netif, NULL);
+
+       scratchlen = sizeof(scratch);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
+                       &scratch, &scratchlen), NULL);
+       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )scratchlen, sizeof(scratch), NULL);
+       if (get_skywalk_features() & SK_FEATURE_NETNS) {
+               if (enable_netif) {
+                       T_QUIET; T_EXPECT_EQ(scratch, enable_flowswitch, NULL);
+               } else {
+                       T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
+               }
+       } else {
+               T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
+       }
+
+       scratchlen = sizeof(scratch);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
+                       &scratch, &scratchlen), NULL);
+       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )scratchlen, sizeof(scratch), NULL);
+       if (g_is_ipsec_test && !enable_netif) {
+               T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
+       } else {
+               T_QUIET; T_EXPECT_EQ(scratch, enable_channel, NULL);
+       }
+
+       if (scratch) {
+               uuid_clear(uuid);
+               uuidlen = sizeof(uuid_t);
+               T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                               uuid, &uuidlen), NULL);
+               T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+               T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid), NULL);
+       } else {
+               uuid_clear(uuid);
+               uuidlen = sizeof(uuid_t);
+               T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                               uuid, &uuidlen), ENXIO, NULL);
+               T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+               T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
+       }
+}
+
+static void
+tunsock_get_ifname(int s, char ifname[IFXNAMSIZ])
+{
+       socklen_t optlen = IFXNAMSIZ;
+       T_QUIET; T_WITH_ERRNO; T_ASSERT_POSIX_ZERO(getsockopt(s, SYSPROTO_CONTROL, g_OPT_IFNAME, ifname, &optlen), NULL);
+       T_QUIET; T_ASSERT_TRUE(optlen > 0, NULL);
+       T_QUIET; T_ASSERT_TRUE(ifname[optlen-1] == '\0', NULL);
+       T_QUIET; T_ASSERT_TRUE(strlen(ifname)+1 == optlen, "got ifname \"%s\" len %zd expected %u", ifname, strlen(ifname), optlen);
+}
+
+static short
+ifnet_get_flags(int s, const char ifname[IFNAMSIZ])
+{
+       struct ifreq    ifr;
+       memset(&ifr, 0, sizeof(ifr));
+       strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr), NULL);
+       return ifr.ifr_flags;
+}
+
+static void
+ifnet_add_addr4(const char ifname[IFNAMSIZ], struct in_addr *addr, struct in_addr *mask, struct in_addr *broadaddr)
+{
+       struct sockaddr_in *sin;
+       struct in_aliasreq ifra;
+       int s;
+
+       T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), NULL);
+
+       memset(&ifra, 0, sizeof(ifra));
+       strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
+
+       if (addr != NULL) {
+               sin = &ifra.ifra_addr;
+               sin->sin_len = sizeof(*sin);
+               sin->sin_family = AF_INET;
+               sin->sin_addr = *addr;
+       }
+
+       if (mask != NULL) {
+               sin = &ifra.ifra_mask;
+               sin->sin_len = sizeof(*sin);
+               sin->sin_family = AF_INET;
+               sin->sin_addr = *mask;
+       }
+
+       if (broadaddr != NULL || (addr != NULL &&
+                 (ifnet_get_flags(s, ifname) & IFF_POINTOPOINT) != 0)) {
+               sin = &ifra.ifra_broadaddr;
+               sin->sin_len = sizeof(*sin);
+               sin->sin_family = AF_INET;
+               sin->sin_addr = (broadaddr != NULL) ? *broadaddr : *addr;
+       }
+
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(s, SIOCAIFADDR, &ifra), NULL);
+
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(s), NULL);
+}
+
+static int g_pfkeyso = -1;
+static struct in_addr g_addr1, g_addr2;
+
+static void
+create_sa(const char ifname[IFXNAMSIZ], uint8_t type, uint32_t spi, struct in_addr *src, struct in_addr *dst)
+{
+       if (g_pfkeyso == -1) {
+               T_QUIET; T_EXPECT_POSIX_SUCCESS(g_pfkeyso = socket(PF_KEY, SOCK_RAW, PF_KEY_V2), NULL);
+       }
+
+       /*
+               <base, SA, (lifetime(HS),) address(SD), (address(P),)
+               key(AE), (identity(SD),) (sensitivity)>
+       */
+
+       struct {
+               struct sadb_msg msg __attribute((aligned(sizeof (uint64_t))));
+               struct sadb_key key  __attribute((aligned(sizeof (uint64_t))));
+               struct sadb_sa sa  __attribute((aligned(sizeof (uint64_t))));
+               struct sadb_x_sa2 sa2  __attribute((aligned(sizeof (uint64_t))));
+               struct sadb_x_ipsecif ipsecif __attribute((aligned(sizeof (uint64_t))));
+               struct {
+                       struct sadb_address addr __attribute((aligned(sizeof (uint64_t))));
+                       struct sockaddr_in saddr __attribute((aligned(sizeof (uint64_t))));
+               } src;
+               struct {
+                       struct sadb_address addr __attribute((aligned(sizeof (uint64_t))));
+                       struct sockaddr_in saddr __attribute((aligned(sizeof (uint64_t))));
+               } dst;
+       } addcmd;
+
+       memset(&addcmd, 0, sizeof(addcmd));
+
+       addcmd.msg.sadb_msg_version = PF_KEY_V2;
+       addcmd.msg.sadb_msg_type = type;
+       addcmd.msg.sadb_msg_errno = 0;
+       addcmd.msg.sadb_msg_satype = SADB_SATYPE_ESP;
+       addcmd.msg.sadb_msg_len = PFKEY_UNIT64(sizeof(addcmd));
+       addcmd.msg.sadb_msg_reserved = 0;
+       addcmd.msg.sadb_msg_seq = 0;
+       addcmd.msg.sadb_msg_pid = (unsigned)getpid();
+
+       addcmd.key.sadb_key_len = PFKEY_UNIT64(sizeof(addcmd.key));
+       addcmd.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
+  addcmd.key.sadb_key_bits = 0;
+  addcmd.key.sadb_key_reserved = 0;
+
+  addcmd.sa.sadb_sa_len = PFKEY_UNIT64(sizeof(addcmd.sa));
+  addcmd.sa.sadb_sa_exttype = SADB_EXT_SA;
+  addcmd.sa.sadb_sa_spi = htonl(spi);
+  addcmd.sa.sadb_sa_replay = 0;
+  addcmd.sa.sadb_sa_state = 0;
+  addcmd.sa.sadb_sa_auth = SADB_AALG_NONE;
+  addcmd.sa.sadb_sa_encrypt = SADB_EALG_NULL;
+  addcmd.sa.sadb_sa_flags = SADB_X_EXT_CYCSEQ;
+
+       addcmd.sa2.sadb_x_sa2_len = PFKEY_UNIT64(sizeof(addcmd.sa2));
+       addcmd.sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
+       addcmd.sa2.sadb_x_sa2_mode = IPSEC_MODE_ANY;
+       addcmd.sa2.sadb_x_sa2_alwaysexpire = 1;
+       addcmd.sa2.sadb_x_sa2_flags = SADB_X_EXT_SA2_DELETE_ON_DETACH;
+       addcmd.sa2.sadb_x_sa2_sequence = 0;
+       addcmd.sa2.sadb_x_sa2_reqid = 0;
+
+       addcmd.ipsecif.sadb_x_ipsecif_len = PFKEY_UNIT64(sizeof(addcmd.ipsecif));
+       addcmd.ipsecif.sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF;
+       memset(addcmd.ipsecif.sadb_x_ipsecif_internal_if, 0, sizeof(addcmd.ipsecif.sadb_x_ipsecif_internal_if));
+       memset(addcmd.ipsecif.sadb_x_ipsecif_outgoing_if, 0, sizeof(addcmd.ipsecif.sadb_x_ipsecif_outgoing_if));
+       strlcpy(addcmd.ipsecif.sadb_x_ipsecif_ipsec_if, ifname, sizeof(addcmd.ipsecif.sadb_x_ipsecif_ipsec_if));
+       addcmd.ipsecif.sadb_x_ipsecif_init_disabled = 0;
+       addcmd.ipsecif.reserved = 0;
+
+  addcmd.src.addr.sadb_address_len = PFKEY_UNIT64(sizeof(addcmd.src));
+  addcmd.src.addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+  addcmd.src.addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
+  addcmd.src.addr.sadb_address_prefixlen = sizeof(struct in_addr) << 3; //XXX Why?
+       addcmd.src.addr.sadb_address_reserved = 0;
+       addcmd.src.saddr.sin_len = sizeof(addcmd.src.saddr);
+       addcmd.src.saddr.sin_family = AF_INET;
+       addcmd.src.saddr.sin_port = htons(0);
+       addcmd.src.saddr.sin_addr = *src;
+
+  addcmd.dst.addr.sadb_address_len = PFKEY_UNIT64(sizeof(addcmd.dst));
+  addcmd.dst.addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+  addcmd.dst.addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
+       addcmd.dst.addr.sadb_address_prefixlen = sizeof(struct in_addr) << 3; //XXX Why?
+       addcmd.dst.addr.sadb_address_reserved = 0;
+       addcmd.dst.saddr.sin_len = sizeof(addcmd.dst.saddr);
+       addcmd.dst.saddr.sin_family = AF_INET;
+       addcmd.dst.saddr.sin_port = htons(0);
+       addcmd.dst.saddr.sin_addr = *dst;
+
+       //log_hexdump(&addcmd, sizeof(addcmd));
+
+       ssize_t slen;
+       T_QUIET; T_EXPECT_POSIX_SUCCESS(slen = send(g_pfkeyso, &addcmd, sizeof(addcmd), 0), NULL);
+       T_QUIET; T_EXPECT_EQ(slen, (ssize_t)sizeof(addcmd), NULL);
+}
+
+/* Unfortunately, connect can return EBUSY due to:
+ * <rdar://problem/33832735> Always return EBUSY if interface with the same name is in delayed detach even if the unique ID is different.
+ *
+ * We should fix that so we don't return EBUSY when we aren't
+ * requesting a specific interface name, but until then workaround it
+ * in the test.
+ */
+
+static int
+try_connect(int socket, const struct sockaddr *address, socklen_t address_len)
+{
+       int ret;
+       while (1) {
+               ret = connect(socket, address, address_len);
+               if (ret != -1 || errno != EBUSY)
+                       return ret;
+               sleep(1);
+       }
+}
+
+static int
+create_tunsock(int enable_netif, int enable_flowswitch, int enable_channel)
+{
+       int tunsock;
+       struct ctl_info kernctl_info;
+       struct sockaddr_ctl kernctl_addr;
+       uuid_t uuid;
+       socklen_t uuidlen;
+
+       T_QUIET; T_EXPECT_POSIX_SUCCESS(tunsock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), NULL);
+
+       memset(&kernctl_info, 0, sizeof(kernctl_info));
+       strlcpy(kernctl_info.ctl_name, g_CONTROL_NAME, sizeof(kernctl_info.ctl_name));
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(tunsock, CTLIOCGINFO, &kernctl_info), NULL);
+
+       memset(&kernctl_addr, 0, sizeof(kernctl_addr));
+       kernctl_addr.sc_len = sizeof(kernctl_addr);
+       kernctl_addr.sc_family = AF_SYSTEM;
+       kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
+       kernctl_addr.sc_id = kernctl_info.ctl_id;
+       kernctl_addr.sc_unit = 0;
+
+       //T_LOG("enable_netif = %d, enable_flowswitch = %d, enable_channel = %d",
+       //enable_netif, enable_channel, enable_flowswitch);
+
+       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
+                       &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
+                       &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
+                       &enable_channel, sizeof(enable_channel)), EINVAL, NULL);
+       uuid_clear(uuid);
+       uuidlen = sizeof(uuid_t);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                       uuid, &uuidlen), EINVAL, NULL);
+       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+       T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
+
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(bind(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
+
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
+                               &enable_netif, sizeof(enable_netif)), NULL);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
+                       &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
+                       &enable_channel, sizeof(enable_channel)), EINVAL, NULL);
+       uuid_clear(uuid);
+       uuidlen = sizeof(uuid_t);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                       uuid, &uuidlen), ENXIO, NULL);
+       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+       T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
+
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(try_connect(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
+
+       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
+                       &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
+
+       if (get_skywalk_features() & SK_FEATURE_NETNS) {
+               if (enable_netif) {
+                       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
+                                       &enable_flowswitch, sizeof(enable_flowswitch)), NULL);
+               } else {
+                       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
+                                       &enable_flowswitch, sizeof(enable_flowswitch)), ENOENT, NULL);
+               }
+       } else {
+               T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
+                               &enable_flowswitch, sizeof(enable_flowswitch)), ENOTSUP, NULL);
+       }
+
+       if (enable_channel) {
+               if (g_is_ipsec_test && !enable_netif) {
+                       /* ipsec doesn't support channels without a netif */
+                       T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
+                                       &enable_channel, sizeof(enable_channel)), EOPNOTSUPP, NULL);
+                       uuid_clear(uuid);
+                       uuidlen = sizeof(uuid_t);
+                       T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                                       uuid, &uuidlen), ENXIO, NULL);
+                       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+                       T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
+               } else {
+                       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
+                                       &enable_channel, sizeof(enable_channel)), NULL);
+                       uuid_clear(uuid);
+                       uuidlen = sizeof(uuid_t);
+                       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                                       uuid, &uuidlen), NULL);
+                       T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+                       T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid), NULL);
+               }
+       } else {
+               T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
+                               &enable_channel, sizeof(enable_channel)), ENXIO, NULL);
+               uuid_clear(uuid);
+               uuidlen = sizeof(uuid_t);
+               T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
+                               uuid, &uuidlen), ENXIO, NULL);
+               T_QUIET; T_EXPECT_EQ_ULONG((unsigned long )uuidlen, sizeof(uuid_t), NULL);
+               T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid), NULL);
+       }
+
+       check_enables(tunsock, enable_netif, enable_flowswitch, enable_channel, uuid);
+
+       //T_LOG("Returning tunsock %d", tunsock);
+
+       return tunsock;
+}
+
+#if 0
+static void
+ipsec_stats(void)
+{
+       struct ifmibdata ifmd;
+
+               len = sizeof(struct ifmibdata);
+               name[3] = IFMIB_IFDATA;
+               name[4] = interesting_row;
+               name[5] = IpFDATA_GENERAL;
+               if (sysctl(name, 6, &ifmd, &len, (void *)0, 0) == -1)
+                       err(1, "sysctl IFDATA_GENERAL %d", interesting_row);
+}
+#endif
+
+static void
+permute_enables(void)
+{
+       int tunsock;
+       T_EXPECT_GE(tunsock = create_tunsock(false, false, false), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(false, false, true), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(false, true, false), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(false, true, true), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(true, false, false), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(true, false, true), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(true, true, false), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+       T_EXPECT_GE(tunsock = create_tunsock(true, true, true), 0, NULL);
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
+}
+
+T_DECL(ipsec_enables, "This test checks combinations of netif/channel/flowswitch on ipsec")
+{
+       setup_ipsec_test();
+       permute_enables();
+}
+
+T_DECL(utun_enables, "This test checks combinations of netif/channel/flowswitch on utun")
+{
+       setup_utun_test();
+       permute_enables();
+}
+
+static int g_tunsock = -1;
+
+static void
+cleanup_tunsock(void)
+{
+       T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(g_tunsock), NULL);
+       T_QUIET; T_EXPECT_POSIX_FAILURE(close(g_tunsock), EBADF, NULL);
+       if (g_is_ipsec_test) {
+               T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(g_pfkeyso), NULL);
+               T_QUIET; T_EXPECT_POSIX_FAILURE(close(g_pfkeyso), EBADF, NULL);
+       }
+}
+
+static void
+setup_tunsock(void)
+{
+       T_ASSERT_GE(g_tunsock = create_tunsock(true, false, true), 0, NULL);
+       T_ATEND(cleanup_tunsock);
+
+       char ifname[IFXNAMSIZ];
+       tunsock_get_ifname(g_tunsock, ifname);
+
+       T_LOG("Created interface %s", ifname);
+
+       uint32_t ifaddr = (10 << 24) | ((unsigned)getpid()&0xffff) << 8 | 160;
+       struct in_addr mask;
+       g_addr1.s_addr = htonl(ifaddr);
+       g_addr2.s_addr = htonl(ifaddr+1);
+       mask.s_addr = htonl(0xffffffff);
+
+       ifnet_add_addr4(ifname, &g_addr1, &mask, &g_addr2);
+
+       if (g_is_ipsec_test) {
+               create_sa(ifname, SADB_ADD, 12345, &g_addr1, &g_addr2);
+               create_sa(ifname, SADB_ADD, 12346, &g_addr2, &g_addr1);
+       }
+}
+
+T_DECL(setup_ipsec, "This test sets up an ipsec interface")
+{
+       setup_ipsec_test();
+       setup_tunsock();
+}
+
+T_DECL(setup_utun, "This test sets up a utun interface")
+{
+       setup_utun_test();
+       setup_tunsock();
+}
index 87f0657d1fb09df805953034d683bc1be4295a93..c14f92a6fe254aeb859ff2ffbd21c8701a87f588 100644 (file)
@@ -45,8 +45,8 @@ __RCSID("$NetBSD: t_utimensat.c,v 1.6 2017/01/10 15:13:56 christos Exp $");
 #include <darwintest.h>
 #include <darwintest_utils.h>
 
-#define DIR "dir"
-#define FILE "dir/utimensat"
+#define DIRPATH "dir"
+#define FILEPATH "dir/utimensat"
 #define BASEFILE "utimensat"
 #define LINK "dir/symlink"
 #define BASELINK "symlink"
@@ -63,9 +63,16 @@ static void chtmpdir(void)
        T_ASSERT_POSIX_ZERO(chdir(dt_tmpdir()), NULL);
 
        // <rdar://problem/31780295> dt_tmpdir() should guarantee a clean directory for each run
-       unlink(FILE);
+       unlink(FILEPATH);
        unlink(LINK);
-       rmdir(DIR);
+       rmdir(DIRPATH);
+
+       // Skip the test if the current working directory is not on APFS.
+       struct statfs sfs = { 0 };
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(statfs(".", &sfs), NULL);
+       if (memcmp(&sfs.f_fstypename[0], "apfs", strlen("apfs")) != 0) {
+               T_SKIP("utimensat is APFS-only, but working directory is non-APFS");
+       }
 
        T_SETUPEND;
 }
@@ -78,15 +85,15 @@ T_DECL(netbsd_utimensat_fd, "See that utimensat works with fd")
        int fd;
        struct stat st;
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
-       T_ASSERT_POSIX_SUCCESS((fd = open(FILE, O_CREAT|O_RDWR, 0644)), NULL);
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
+       T_ASSERT_POSIX_SUCCESS((fd = open(FILEPATH, O_CREAT|O_RDWR, 0644)), NULL);
        T_ASSERT_POSIX_ZERO(close(fd), NULL);
 
-       T_ASSERT_POSIX_SUCCESS((dfd = open(DIR, O_RDONLY, 0)), NULL);
+       T_ASSERT_POSIX_SUCCESS((dfd = open(DIRPATH, O_RDONLY, 0)), NULL);
        T_ASSERT_POSIX_ZERO(utimensat(dfd, BASEFILE, tptr, 0), NULL);
        T_ASSERT_POSIX_ZERO(close(dfd), NULL);
 
-       T_ASSERT_POSIX_ZERO(stat(FILE, &st), NULL);
+       T_ASSERT_POSIX_ZERO(stat(FILEPATH, &st), NULL);
        T_ASSERT_EQ(st.st_atimespec.tv_sec, tptr[0].tv_sec, NULL);
        T_ASSERT_EQ(st.st_atimespec.tv_nsec, tptr[0].tv_nsec, NULL);
        T_ASSERT_EQ(st.st_mtimespec.tv_sec, tptr[1].tv_sec, NULL);
@@ -100,11 +107,11 @@ T_DECL(netbsd_utimensat_fdcwd, "See that utimensat works with fd as AT_FDCWD")
        int fd;
        struct stat st;
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
-       T_ASSERT_POSIX_SUCCESS((fd = open(FILE, O_CREAT|O_RDWR, 0644)), NULL);
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
+       T_ASSERT_POSIX_SUCCESS((fd = open(FILEPATH, O_CREAT|O_RDWR, 0644)), NULL);
        T_ASSERT_POSIX_ZERO(close(fd), NULL);
 
-       T_ASSERT_POSIX_ZERO(chdir(DIR), NULL);
+       T_ASSERT_POSIX_ZERO(chdir(DIRPATH), NULL);
        T_ASSERT_POSIX_ZERO(utimensat(AT_FDCWD, BASEFILE, tptr, 0), NULL);
 
        T_ASSERT_POSIX_ZERO(stat(BASEFILE, &st), NULL);
@@ -118,7 +125,7 @@ T_DECL(netbsd_utimensat_fdcwderr, "See that utimensat fails with fd as AT_FDCWD
 {
        chtmpdir();
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
        T_ASSERT_EQ(utimensat(AT_FDCWD, FILEERR, tptr, 0), -1, NULL);
 }
 
@@ -128,8 +135,8 @@ T_DECL(netbsd_utimensat_fderr1, "See that utimensat fail with bad path")
 
        int dfd;
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
-       T_ASSERT_POSIX_SUCCESS((dfd = open(DIR, O_RDONLY, 0)), NULL);
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
+       T_ASSERT_POSIX_SUCCESS((dfd = open(DIRPATH, O_RDONLY, 0)), NULL);
        T_ASSERT_EQ(utimensat(dfd, FILEERR, tptr, 0), -1, NULL);
        T_ASSERT_POSIX_ZERO(close(dfd), NULL);
 }
@@ -142,8 +149,8 @@ T_DECL(netbsd_utimensat_fderr2, "See that utimensat fails with bad fdat")
        int fd;
        char cwd[MAXPATHLEN];
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
-       T_ASSERT_POSIX_SUCCESS((fd = open(FILE, O_CREAT|O_RDWR, 0644)), NULL);
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
+       T_ASSERT_POSIX_SUCCESS((fd = open(FILEPATH, O_CREAT|O_RDWR, 0644)), NULL);
        T_ASSERT_POSIX_ZERO(close(fd), NULL);
 
        T_ASSERT_POSIX_SUCCESS((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)), NULL);
@@ -157,11 +164,11 @@ T_DECL(netbsd_utimensat_fderr3, "See that utimensat fails with fd as -1")
 
        int fd;
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
-       T_ASSERT_POSIX_SUCCESS((fd = open(FILE, O_CREAT|O_RDWR, 0644)), NULL);
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
+       T_ASSERT_POSIX_SUCCESS((fd = open(FILEPATH, O_CREAT|O_RDWR, 0644)), NULL);
        T_ASSERT_POSIX_ZERO(close(fd), NULL);
 
-       T_ASSERT_EQ(utimensat(-1, FILE, tptr, 0), -1, NULL);
+       T_ASSERT_EQ(utimensat(-1, FILEPATH, tptr, 0), -1, NULL);
 }
 
 T_DECL(netbsd_utimensat_fdlink, "See that utimensat works on symlink")
@@ -171,10 +178,10 @@ T_DECL(netbsd_utimensat_fdlink, "See that utimensat works on symlink")
        int dfd;
        struct stat st;
 
-       T_ASSERT_POSIX_ZERO(mkdir(DIR, 0755), NULL);
-       T_ASSERT_POSIX_ZERO(symlink(FILE, LINK), NULL); /* NB: FILE does not exists */
+       T_ASSERT_POSIX_ZERO(mkdir(DIRPATH, 0755), NULL);
+       T_ASSERT_POSIX_ZERO(symlink(FILEPATH, LINK), NULL); /* NB: FILE does not exists */
 
-       T_ASSERT_POSIX_SUCCESS((dfd = open(DIR, O_RDONLY, 0)), NULL);
+       T_ASSERT_POSIX_SUCCESS((dfd = open(DIRPATH, O_RDONLY, 0)), NULL);
 
        T_ASSERT_EQ(utimensat(dfd, BASELINK, tptr, 0), -1, NULL);
        T_ASSERT_EQ(errno, ENOENT, NULL);
diff --git a/tools/tests/darwintests/network_entitlements.plist b/tools/tests/darwintests/network_entitlements.plist
new file mode 100644 (file)
index 0000000..c326c83
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.security.network.client</key>
+       <true/>
+       <key>com.apple.security.network.server</key>
+       <true/>
+</dict>
+</plist>
diff --git a/tools/tests/darwintests/no32exec_35914211.c b/tools/tests/darwintests/no32exec_35914211.c
new file mode 100644 (file)
index 0000000..ea36703
--- /dev/null
@@ -0,0 +1,23 @@
+#include <spawn.h>
+#include <sys/wait.h>
+#include <darwintest.h>
+#include <mach-o/dyld.h>
+#include <errno.h>
+
+T_DECL(no32exec_bootarg, "make sure the no32exec boot-arg is honored", T_META_BOOTARGS_SET("-no32exec"))
+{
+       int spawn_ret, pid;
+       char path[1024];
+       uint32_t size = sizeof(path);
+
+       T_ASSERT_EQ(_NSGetExecutablePath(path, &size), 0, NULL);
+       T_ASSERT_LT(strlcat(path, "_helper", size), size, NULL);
+
+       spawn_ret = posix_spawn(&pid, path, NULL, NULL, NULL, NULL);
+       if (spawn_ret == 0) {
+               int wait_ret = 0;
+               waitpid(pid, &wait_ret, 0);
+               T_ASSERT_FALSE(WIFEXITED(wait_ret), "i386 helper should not run");
+       }
+       T_ASSERT_EQ(spawn_ret, EBADARCH, NULL);
+}
diff --git a/tools/tests/darwintests/no32exec_35914211_helper.c b/tools/tests/darwintests/no32exec_35914211_helper.c
new file mode 100644 (file)
index 0000000..99fb6be
--- /dev/null
@@ -0,0 +1,6 @@
+#include <darwintest.h>
+
+T_DECL(null_test, "nothing to see here")
+{
+       T_SKIP("nothing to see here");
+}
index b0c6fa112f3ae8a0457fe7ff653516ad61594ba8..1d3b23d2c996fb009ff23d15d0c1463fbec44ba0 100644 (file)
@@ -1,13 +1,13 @@
+#include <stdio.h>
+#include <signal.h>
+#include <sys/sysctl.h>
+#include <mach-o/dyld.h>
+
 #ifdef T_NAMESPACE
 #undef T_NAMESPACE
 #endif
 #include <darwintest.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/sysctl.h>
+#include <darwintest_utils.h>
 
 T_GLOBAL_META(
        T_META_NAMESPACE("xnu.vm.perf"),
@@ -21,12 +21,38 @@ enum {
        TYPICAL
 };
 
+#define CREATE_LIST(X) \
+       X(SUCCESS) \
+       X(TOO_FEW_ARGUMENTS) \
+       X(SYSCTL_VM_PAGESIZE_FAILED) \
+       X(VM_PAGESIZE_IS_ZERO) \
+       X(UNKNOWN_PAGE_TYPE) \
+       X(DISPATCH_SOURCE_CREATE_FAILED) \
+       X(INITIAL_SIGNAL_TO_PARENT_FAILED) \
+       X(SIGNAL_TO_PARENT_FAILED) \
+       X(EXIT_CODE_MAX)
+
+#define EXIT_CODES_ENUM(VAR) VAR,
+enum exit_codes_num {
+       CREATE_LIST(EXIT_CODES_ENUM)
+};
+
+#define EXIT_CODES_STRING(VAR) #VAR,
+static const char *exit_codes_str[] = {
+       CREATE_LIST(EXIT_CODES_STRING)
+};
+
+
+static pid_t pid = -1;
+static dt_stat_t r;
+static dt_stat_time_t s;
+
 void allocate_zero_pages(char **buf, int num_pages, int vmpgsize);
 void allocate_mostly_zero_pages(char **buf, int num_pages, int vmpgsize);
 void allocate_random_pages(char **buf, int num_pages, int vmpgsize);
 void allocate_representative_pages(char **buf, int num_pages, int vmpgsize);
-void allocate_pages(int size_mb, int page_type);
 void run_compressor_test(int size_mb, int page_type);
+void freeze_helper_process(void);
 
 void allocate_zero_pages(char **buf, int num_pages, int vmpgsize) {
        int i;
@@ -68,26 +94,158 @@ void allocate_representative_pages(char **buf, int num_pages, int vmpgsize) {
                val = 0;
                for (i = 0; i < vmpgsize; i += 16) {
                        memset(&buf[j][i], val, 16);
-                       if (i < 3700 * (vmpgsize / 4096)) {
+                       if (i < 3400 * (vmpgsize / 4096)) {
                                val++;
                        }
                }
        }
 }
 
-void allocate_pages(int size_mb, int page_type) {
-       int num_pages = 0;
-       int vmpgsize, i, j;
-       char **buf;
+void freeze_helper_process(void) {
+       int ret;
+       int64_t compressed_before, compressed_after, input_before, input_after;
+       size_t length;
+
+       /*
+        * Wait a bit after the pages have been allocated/accessed before trying to freeze.
+        * The sleeps are not needed, they just separate the operations into three logical chunks:
+        * touch a few pages, freeze them, thaw them (and repeat).
+        */
+       usleep(100);
+       length = sizeof(compressed_before);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_compressed_bytes", &compressed_before, &length, NULL, 0),
+                       "failed to query vm.compressor_compressed_bytes");
+       length = sizeof(input_before);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_input_bytes", &input_before, &length, NULL, 0),
+                       "failed to query vm.compressor_input_bytes");
+
+       T_STAT_MEASURE(s) {
+               ret = sysctlbyname("kern.memorystatus_freeze", NULL, NULL, &pid, sizeof(pid));
+       };
+
+       length = sizeof(compressed_after);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_compressed_bytes", &compressed_after, &length, NULL, 0),
+                       "failed to query vm.compressor_compressed_bytes");
+       length = sizeof(input_after);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_input_bytes", &input_after, &length, NULL, 0),
+                       "failed to query vm.compressor_input_bytes");
+
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.memorystatus_freeze failed on pid %d", pid);
+
+       dt_stat_add(r, (double)(input_after - input_before)/(double)(compressed_after - compressed_before));
+
+       /* Wait a bit after freezing before trying to thaw */
+       usleep(100);
+       ret = sysctlbyname("kern.memorystatus_thaw", NULL, NULL, &pid, sizeof(pid));
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.memorystatus_thaw failed on pid %d", pid);
+
+       /* Wait a bit after thawing before pages can be re-accessed */
+       usleep(100);
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(kill(pid, SIGUSR1), "failed to send SIGUSR1 to child process [%d]", pid);
+}
+
+void run_compressor_test(int size_mb, int page_type) {
+       int ret;
+       char sz_str[50];
+       char pt_str[50];
+       char **launch_tool_args;
+       char testpath[PATH_MAX];
+       uint32_t testpath_buf_size;
+       dispatch_source_t ds_freeze, ds_proc;
+
+#ifndef CONFIG_FREEZE
+       T_SKIP("Task freeze not supported.");
+#endif
+
+       r = dt_stat_create("(input bytes / compressed bytes)", "compression_ratio");
+       s = dt_stat_time_create("compressor_latency");
+
+       signal(SIGUSR1, SIG_IGN);
+       ds_freeze = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGUSR1, 0, dispatch_get_main_queue());
+       T_QUIET; T_ASSERT_NOTNULL(ds_freeze, "dispatch_source_create (ds_freeze)");
+
+       dispatch_source_set_event_handler(ds_freeze, ^{
+               if (!dt_stat_stable(s)) {
+                       freeze_helper_process();
+               } else {
+                       dt_stat_finalize(s);
+                       dt_stat_finalize(r);
+
+                       kill(pid, SIGKILL);
+                       dispatch_source_cancel(ds_freeze);
+               }
+       });
+       dispatch_activate(ds_freeze);
+
+       testpath_buf_size = sizeof(testpath);
+       ret = _NSGetExecutablePath(testpath, &testpath_buf_size);
+       T_QUIET; T_ASSERT_POSIX_ZERO(ret, "_NSGetExecutablePath");
+       T_LOG("Executable path: %s", testpath);
+
+       sprintf(sz_str, "%d", size_mb);
+       sprintf(pt_str, "%d", page_type);
+       launch_tool_args = (char *[]){
+               testpath,
+               "-n",
+               "allocate_pages",
+               "--",
+               sz_str,
+               pt_str,
+               NULL
+       };
+
+       /* Spawn the child process. Suspend after launch until the exit proc handler has been set up. */
+       ret = dt_launch_tool(&pid, launch_tool_args, true, NULL, NULL);
+       if (ret != 0) {
+               T_LOG("dt_launch tool returned %d with error code %d", ret, errno);
+       }
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "dt_launch_tool");
+
+       ds_proc = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, (uintptr_t)pid, DISPATCH_PROC_EXIT, dispatch_get_main_queue());
+       T_QUIET; T_ASSERT_NOTNULL(ds_proc, "dispatch_source_create (ds_proc)");
+
+       dispatch_source_set_event_handler(ds_proc, ^{
+               int status = 0, code = 0;
+               pid_t rc = waitpid(pid, &status, 0);
+               T_QUIET; T_ASSERT_EQ(rc, pid, "waitpid");
+               code = WEXITSTATUS(status);
+
+               if (code == 0) {
+                       T_END;
+               } else if (code > 0 && code < EXIT_CODE_MAX) {
+                       T_ASSERT_FAIL("Child exited with %s", exit_codes_str[code]);
+               } else {
+                       T_ASSERT_FAIL("Child exited with unknown exit code %d", code);
+               }
+       });
+       dispatch_activate(ds_proc);
+
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(kill(pid, SIGCONT), "failed to send SIGCONT to child process [%d]", pid);
+       dispatch_main();
+}
+
+T_HELPER_DECL(allocate_pages, "allocates pages to compress") {
+       int i, j, ret, size_mb, page_type, vmpgsize;
        size_t vmpgsize_length;
+       __block int num_pages;
+       __block char **buf;
+       dispatch_source_t ds_signal;
 
        vmpgsize_length = sizeof(vmpgsize);
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.pagesize", &vmpgsize, &vmpgsize_length, NULL, 0),
-                       "failed to query vm.pagesize");
+       ret = sysctlbyname("vm.pagesize", &vmpgsize, &vmpgsize_length, NULL, 0);
+       if (ret != 0) {
+               exit(SYSCTL_VM_PAGESIZE_FAILED);
+       }
        if (vmpgsize == 0) {
-               T_FAIL("vm.pagesize set to zero");
+               exit(VM_PAGESIZE_IS_ZERO);
+       }
+
+       if (argc < 2) {
+               exit(TOO_FEW_ARGUMENTS);
        }
 
+       size_mb = atoi(argv[0]);
+       page_type = atoi(argv[1]);
        num_pages = size_mb * 1024 * 1024 / vmpgsize;
        buf = (char**)malloc(sizeof(char*) * (size_t)num_pages);
 
@@ -106,103 +264,41 @@ void allocate_pages(int size_mb, int page_type) {
                        allocate_representative_pages(buf, num_pages, vmpgsize);
                        break;
                default:
-                       T_FAIL("unknown page type");
-                       break;
+                       exit(UNKNOWN_PAGE_TYPE);
        }
 
-       for(j = 0; j < num_pages; j++) {
-               i = buf[j][1];
+       for (j = 0; j < num_pages; j++) {
+               i = buf[j][0];
        }
-}
-
-
-void run_compressor_test(int size_mb, int page_type) {
-
-#ifndef CONFIG_FREEZE
-       T_SKIP("Task freeze not supported.");
-#endif
-
-       dt_stat_t r = dt_stat_create("(input bytes / compressed bytes)", "compression_ratio");
-       dt_stat_time_t s = dt_stat_time_create("compressor_latency");
-
-       while (!dt_stat_stable(s)) {
-               pid_t pid;
-               int parent_pipe[2], child_pipe[2];
-
-               T_QUIET; T_ASSERT_POSIX_SUCCESS(pipe(parent_pipe), "pipe failed");
-               T_QUIET; T_ASSERT_POSIX_SUCCESS(pipe(child_pipe), "pipe failed");
-
-               pid = fork();
-               T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "fork failed with %d", errno);
 
-               if (pid == 0) {
-                       int val = 1;
-
-                       close(child_pipe[0]);
-                       close(parent_pipe[1]);
-                       allocate_pages(size_mb, page_type);
-
-                       // Indicates to the parent that the child has finished allocating pages
-                       write(child_pipe[1], &val, sizeof(val));
-
-                       // Parent is done with the freeze, ok to exit now
-                       read(parent_pipe[0], &val, sizeof(val));
-                       if (val != 2) {
-                               T_FAIL("pipe read error");
-                       }
-                       close(child_pipe[1]);
-                       close(parent_pipe[0]);
-                       exit(0);
-
-               } else {
-                       int val, ret;
-                       int64_t compressed_before, compressed_after, input_before, input_after;
-                       dt_stat_token start_token;
-                       size_t length = sizeof(compressed_before);
-
-                       close(child_pipe[1]);
-                       close(parent_pipe[0]);
-
-                       // Wait for the child to finish allocating pages
-                       read(child_pipe[0], &val, sizeof(val));
-                       if (val != 1) {
-                               T_FAIL("pipe read error");
-                       }
-                       // Just to be extra sure that the child has finished allocating all of its pages
-                       usleep(100);
-
-                       T_LOG("attempting to freeze pid %d\n", pid);
-
-                       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_compressed_bytes", &compressed_before, &length, NULL, 0),
-                                       "failed to query vm.compressor_compressed_bytes");
-                       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_input_bytes", &input_before, &length, NULL, 0),
-                                       "failed to query vm.compressor_input_bytes");
-
-                       start_token = dt_stat_time_begin(s);
-                       ret = sysctlbyname("kern.memorystatus_freeze", NULL, NULL, &pid, (size_t)sizeof(int));
-                       dt_stat_time_end(s, start_token);
-
-                       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_compressed_bytes", &compressed_after, &length, NULL, 0),
-                                       "failed to query vm.compressor_compressed_bytes");
-                       T_QUIET; T_ASSERT_POSIX_SUCCESS(sysctlbyname("vm.compressor_input_bytes", &input_after, &length, NULL, 0),
-                                       "failed to query vm.compressor_input_bytes");
-
-                       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.memorystatus_freeze failed on pid %d", pid);
+       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+               /* Signal to the parent that we're done allocating and it's ok to freeze us */
+               printf("Sending initial signal to parent to begin freezing\n");
+               if (kill(getppid(), SIGUSR1) != 0) {
+                       exit(INITIAL_SIGNAL_TO_PARENT_FAILED);
+               }
+       });
 
-                       dt_stat_add(r, (double)(input_after - input_before)/(double)(compressed_after - compressed_before));
+       signal(SIGUSR1, SIG_IGN);
+       ds_signal = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGUSR1, 0, dispatch_get_main_queue());
+       if (ds_signal == NULL) {
+               exit(DISPATCH_SOURCE_CREATE_FAILED);
+       }
 
-                       val = 2;
-                       // Ok for the child to exit now
-                       write(parent_pipe[1], &val, sizeof(val));
-                       usleep(100);
+       dispatch_source_set_event_handler(ds_signal, ^{
+               volatile int tmp;
 
-                       close(child_pipe[0]);
-                       close(parent_pipe[1]);
+               /* Make sure all the pages are accessed before trying to freeze again */
+               for (int x = 0; x < num_pages; x++) {
+                       tmp = buf[x][0];
                }
-       }
+               if (kill(getppid(), SIGUSR1) != 0) {
+                       exit(SIGNAL_TO_PARENT_FAILED);
+               }
+       });
+       dispatch_activate(ds_signal);
 
-       dt_stat_finalize(s);
-       dt_stat_finalize(r);
+       dispatch_main();
 }
 
 // Numbers for 10MB and above are fairly reproducible. Anything smaller shows a lot of variation.
index 169c698c7e4a00e84d14f39a27ae822c73f38d97..bd9a5e7273659da0887ea086e6d20cbc854749ab 100644 (file)
@@ -517,12 +517,11 @@ handle_reading(enum fd_pair fd_pair, int fd)
        T_QUIET; T_ASSERT_LE(final_length, EXPECTED_LEN,
                        "should not read more from file than what can be sent");
 
-       /* FIFOs don't (and TTYs may not) send EOF when the write side closes */
+       /* FIFOs don't send EOF when the write side closes */
        if (final_length == strlen(EXPECTED_STRING) &&
-                       (fd_pair == FIFO_PAIR || fd_pair == PTY_PAIR))
+                       (fd_pair == FIFO_PAIR))
        {
-               T_LOG("read all expected bytes from %s",
-                               fd_pair == FIFO_PAIR ? "FIFO" : "PTY");
+               T_LOG("read all expected bytes from FIFO");
                return false;
        }
        return true;
@@ -611,12 +610,6 @@ read_from_fd(int fd, enum fd_pair fd_pair, enum read_mode mode)
                                "select waited for %d seconds and timed out",
                                READ_TIMEOUT_SECS);
 
-                       if (fd_pair == PTY_PAIR) {
-                               /*
-                                * XXX sometimes a PTY doesn't send EOF when the writer closes
-                                */
-                               T_MAYFAIL;
-                       }
                        /* didn't fail or time out, therefore data is ready */
                        T_QUIET; T_ASSERT_NE(FD_ISSET(fd, &read_fd), 0,
                                        "select should show reading fd as readable");
index 9c2e16f0505f2c250e942f5c4e8f065ec7075af6..3a1e73820f78047fe3b62ba161171ab9913bddfc 100644 (file)
+#define PRIVATE
+#include <System/sys/kdebug.h>
 #include <darwintest.h>
+#include <darwintest_utils.h>
+#include <dispatch/dispatch.h>
+#include <fcntl.h>
 #include <inttypes.h>
+#include <libproc.h>
 #include <limits.h>
+#include <mach/mach.h>
+#include <mach/policy.h>
 #include <os/assumes.h>
 #include <os/overflow.h>
+#include <pthread.h>
+#include <signal.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/proc_info.h>
+#include <sys/stat.h>
 #include <sys/sysctl.h>
-#include <System/sys/kdebug.h>
+#include <sys/vnode.h>
 #include <unistd.h>
-
-#define PRIVATE
-#include <sys/proc_info.h>
-#include <sys/event.h>
-#include <libproc.h>
 #undef PRIVATE
 
-T_GLOBAL_META(T_META_NAMESPACE("xnu.all"));
+#define ACT_CHANGE_UID 1
+#define ACT_CHANGE_RUID 2
+#define ACT_EXIT 127
+
+#define ACT_PHASE2 2
+#define ACT_PHASE3 3
+#define ACT_PHASE4 4
+#define ACT_PHASE5 5
+
+#define PIPE_IN 0
+#define PIPE_OUT 1
+
+#define CONF_THREAD_NAME "test_child_thread"
+#define CONF_CMD_NAME getprogname()
+#define CONF_PROC_COUNT 20
+#define CONF_BLK_SIZE 4096
+#define CONF_UID_VAL 999U
+#define CONF_RUID_VAL 998U
+#define CONF_GID_VAL 997U
+#define CONF_NICE_VAL 5
+#define CONF_NUM_THREADS 2
+
+#define BASEPRI_DEFAULT 31
+#define MAXPRI_USER 63
+
+#define CONF_OPN_FILE_COUNT 3
+#define CONF_TMP_FILE_PATH "/tmp/testfile"
+
+uint32_t get_tty_dev(void);
+
+#define WAIT_FOR_CHILDREN(pipefd, action, child_count)                           \
+       do {                                                                         \
+               long ret;                                                                \
+               if (child_count == 1) {                                                  \
+                       int child_ret_action = 999;                                          \
+                       while (child_ret_action != action) {                                 \
+                               ret = read(pipefd, &child_ret_action, sizeof(child_ret_action)); \
+                       }                                                                    \
+               } else {                                                                 \
+                       int child_ready_count = child_count * (int)sizeof(action);           \
+                                                                                 \
+                       action = 0;                                                          \
+                       while (child_ready_count) {                                          \
+                               ret = read(pipefd, &action, (int)sizeof(action));                \
+                               if (ret != -1) {                                                 \
+                                       child_ready_count -= ret;                                    \
+                               } else {                                                         \
+                                       T_FAIL("ERROR: Could not read from pipe() : %d", errno);     \
+                               }                                                                \
+                               if (action) {                                                    \
+                                       T_FAIL("ERROR: Child action failed with error %d", action);  \
+                               }                                                                \
+                       }                                                                    \
+               }                                                                        \
+       } while (0)
+
+#define PROC_INFO_CALL(struct_name, pid, flavor, proc_arg)                                                     \
+       do {                                                                                                       \
+               struct struct_name * struct_var = malloc(sizeof(struct struct_name));                                  \
+               T_QUIET;                                                                                               \
+               T_ASSERT_NOTNULL(struct_var, "malloc() for " #flavor);                                                 \
+               retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, flavor, (uint64_t)proc_arg, (user_addr_t)struct_var, \
+                                    (uint32_t)sizeof(struct struct_name));                                            \
+                                                                                                               \
+               T_QUIET;                                                                                               \
+               T_EXPECT_POSIX_SUCCESS(retval, "__proc_info call for " #flavor);                                       \
+               T_ASSERT_EQ_INT(retval, (int)sizeof(struct struct_name), "__proc_info call for " #flavor);             \
+               ret_structs[i] = (void *)struct_var;                                                                   \
+               i++;                                                                                                   \
+       } while (0)
+
+uint32_t
+get_tty_dev()
+{
+       struct stat buf;
+       stat(ttyname(1), &buf);
+       return ((uint32_t)buf.st_rdev);
+}
+
+/*
+ * Defined in libsyscall/wrappers/libproc/libproc.c
+ * For API test only. For normal use, please use the libproc API instead.
+ * DO NOT COPY
+ */
+extern int __proc_info(int32_t callnum, int32_t pid, uint32_t flavor, uint64_t arg, user_addr_t buffer, int32_t buffersize);
+struct proc_config_s {
+       int parent_pipe[2];
+       int child_count;
+       pid_t proc_grp_id;
+       int child_pipe[CONF_PROC_COUNT][2];
+       int child_pids[CONF_PROC_COUNT];
+       void * cow_map; /* memory for cow test */
+};
+typedef struct proc_config_s * proc_config_t;
+
+typedef void (^child_action_handler_t)(proc_config_t proc_config, int child_id);
+
+enum proc_info_opt {
+       P_UNIQIDINFO    = 0x01,
+       C_UNIQIDINFO    = 0x02,
+       PBSD_OLD        = 0x04,
+       PBSD            = 0x08,
+       PBSD_SHORT      = 0x10,
+       PBSD_UNIQID     = 0x20,
+       P_TASK_INFO     = 0x40,
+       P_TASK_INFO_NEW = 0x80,
+       PALL            = 0x100,
+       THREAD_ADDR     = 0x200,
+       PTHINFO_OLD     = 0x400,
+       PTHINFO         = 0x800,
+       PTHINFO_64      = 0x1000,
+       PINFO_PATH      = 0x2000,
+       PAI             = 0x4000,
+       PREGINFO        = 0x8000,
+       PREGINFO_PATH   = 0x10000,
+       PREGINFO_PATH_2 = 0x20000,
+       PREGINFO_PATH_3 = 0x40000,
+       PVNINFO         = 0x80000
+};
+
+static int tmp_fd = -1;
+
+static child_action_handler_t proc_info_listpids_handler = ^void(proc_config_t proc_config, int child_id) {
+  close(proc_config->parent_pipe[PIPE_IN]);
+  close(proc_config->child_pipe[child_id][PIPE_OUT]);
+  long retval      = 0;
+  int child_action = 0;
+  retval           = write(proc_config->parent_pipe[PIPE_OUT], &child_action, sizeof(child_action));
+  if (retval != -1) {
+         while (child_action != ACT_EXIT) {
+                 retval = read(proc_config->child_pipe[child_id][PIPE_IN], &child_action, sizeof(child_action));
+                 if (retval == 0 || (retval == -1 && errno == EAGAIN)) {
+                         continue;
+                 }
+                 if (retval != -1) {
+                         switch (child_action) {
+                         case ACT_CHANGE_UID:
+                                 /*
+                                  * Change uid
+                                  */
+                                 retval = setuid(CONF_UID_VAL);
+                                 break;
+                         case ACT_CHANGE_RUID:
+                                 /*
+                                  * Change ruid
+                                  */
+                                 retval = setreuid(CONF_RUID_VAL, (uid_t)-1);
+                                 break;
+                         case ACT_EXIT:
+                                 /*
+                                  * Exit
+                                  */
+                                 break;
+                         }
+                 }
+                 if (child_action != ACT_EXIT) {
+                         retval = write(proc_config->parent_pipe[PIPE_OUT], &retval, sizeof(retval));
+                         if (retval == -1)
+                                 break;
+                 }
+         }
+  }
+  close(proc_config->parent_pipe[PIPE_OUT]);
+  close(proc_config->child_pipe[child_id][PIPE_IN]);
+  exit(0);
+};
+
+static child_action_handler_t proc_info_call_pidinfo_handler = ^void(proc_config_t proc_config, int child_id) {
+  close(proc_config->parent_pipe[PIPE_IN]);
+  close(proc_config->child_pipe[child_id][PIPE_OUT]);
+  int action  = 0;
+  long retval = 0;
+  int i;
+  void * tmp_map           = NULL;
+  dispatch_queue_t q       = NULL;
+  dispatch_semaphore_t sem = NULL;
+  /*
+   * PHASE 1: Child ready and waits for parent to send next action
+   */
+  T_LOG("Child ready to accept action from parent");
+  retval = write(proc_config->parent_pipe[PIPE_OUT], &action, sizeof(action));
+  if (retval != -1) {
+         while (action != ACT_EXIT) {
+                 retval = read(proc_config->child_pipe[child_id][PIPE_IN], &action, sizeof(action));
+
+                 if (retval != -1) {
+                         retval = 0;
+                         switch (action) {
+                         case ACT_PHASE2: {
+                                 /*
+                                  * Change uid, euid, guid, rgid, nice value
+                                  * Also change the svuid and svgid
+                                  */
+                                 T_LOG("Child changing uid, euid, rguid, svuid, svgid and nice value");
+                                 retval = nice(CONF_NICE_VAL);
+                                 if (retval == -1) {
+                                         T_LOG("(child) ERROR: nice() failed");
+                                         break;
+                                 }
+                                 retval = setgid(CONF_GID_VAL);
+                                 if (retval == -1) {
+                                         T_LOG("(child) ERROR: setgid() failed");
+                                         break;
+                                 }
+                                 retval = setreuid((uid_t)-1, CONF_RUID_VAL);
+                                 if (retval == -1) {
+                                         T_LOG("(child) ERROR: setreuid() failed");
+                                         break;
+                                 }
+                                 break;
+                         }
+                         case ACT_PHASE3: {
+                                 /*
+                                  * Allocate a page of memory
+                                  * Copy on write shared memory
+                                  */
+                                 T_LOG("Child allocating a page of memory, and causing a copy-on-write");
+                                 retval  = 0;
+                                 tmp_map = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+                                 if (tmp_map == MAP_FAILED) {
+                                         T_LOG("(child) ERROR: mmap() failed");
+                                         retval = 1;
+                                         break;
+                                 }
+                                 /*
+                                  * Get the page allocated
+                                  */
+                                 int * map_ptr = (int *)tmp_map;
+                                 for (i = 0; i < (int)(PAGE_SIZE / sizeof(int)); i++) {
+                                         *map_ptr++ = i;
+                                 }
+                                 /*
+                                  * Cause copy on write to the page
+                                  */
+                                 *((int *)(proc_config->cow_map)) = 20;
+
+                                 break;
+                         }
+                         case ACT_PHASE4: {
+                                 T_LOG("Child spending CPU cycles and changing thread name");
+                                 retval                       = 0;
+                                 int number                   = 1000;
+                                 unsigned long long factorial = 1;
+                                 int j;
+                                 for (j = 1; j <= number; j++) {
+                                         factorial *= (unsigned long long)j;
+                                 }
+                                 sysctlbyname("kern.threadname", NULL, 0, CONF_THREAD_NAME, strlen(CONF_THREAD_NAME));
+                                 break;
+                         }
+                         case ACT_PHASE5: {
+                                 /*
+                                  * Dispatch for Workq test
+                                  */
+                                 T_LOG("Child creating a dispatch queue, and dispatching blocks on it");
+                                 q = dispatch_queue_create("com.apple.test_proc_info.workqtest",
+                                                               DISPATCH_QUEUE_CONCURRENT); // dispatch_get_global_queue(0, 0);
+                                 sem = dispatch_semaphore_create(0);
+
+                                 for (i = 0; i < CONF_NUM_THREADS; i++) {
+                                         dispatch_async(q, ^{
+                                               /*
+                                                * Block the thread, do nothing
+                                                */
+                                               dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
+                                         });
+                                 }
+                                 break;
+                         }
+                         case ACT_EXIT: {
+                                 /*
+                                  * Exit
+                                  */
+                                 if (sem) {
+                                         for (i = 0; i < CONF_NUM_THREADS; i++) {
+                                                 dispatch_semaphore_signal(sem);
+                                         }
+                                 }
+
+                                 if (tmp_map)
+                                         munmap(tmp_map, PAGE_SIZE);
+
+                                 if (proc_config->cow_map)
+                                         munmap(proc_config->cow_map, PAGE_SIZE);
+
+                                 break;
+                         }
+                         }
+                 }
+                 if (action != ACT_EXIT) {
+                         retval = write(proc_config->parent_pipe[PIPE_OUT], &action, sizeof(action));
+                         if (retval == -1)
+                                 break;
+                 }
+         }
+         close(proc_config->parent_pipe[PIPE_OUT]);
+         close(proc_config->child_pipe[child_id][PIPE_IN]);
+         exit(0);
+  }
+};
+
+static void
+free_proc_config(proc_config_t proc_config)
+{
+       free(proc_config);
+}
+
+static void
+send_action_to_child_processes(proc_config_t proc_config, int action)
+{
+       long err;
+       for (int i = 0; i < proc_config->child_count; i++) {
+               err = write(proc_config->child_pipe[i][PIPE_OUT], &action, sizeof(action));
+               T_QUIET;
+               T_ASSERT_POSIX_SUCCESS(err, "write() to child in send_action");
+       }
+       if (action != ACT_EXIT) {
+               WAIT_FOR_CHILDREN(proc_config->parent_pipe[PIPE_IN], action, proc_config->child_count);
+       }
+}
+
+static void
+kill_child_processes(proc_config_t proc_config)
+{
+       int ret = 0;
+       T_LOG("Killing child processes");
+       send_action_to_child_processes(proc_config, ACT_EXIT);
+       for (int child_id = 0; child_id < proc_config->child_count; child_id++) {
+               close(proc_config->child_pipe[child_id][PIPE_OUT]);
+               dt_waitpid(proc_config->child_pids[child_id], NULL, NULL, 5);
+               T_QUIET;
+               T_ASSERT_POSIX_SUCCESS(ret, "killed child %d", child_id);
+       }
+       close(proc_config->parent_pipe[PIPE_IN]);
+       munmap(proc_config->cow_map, PAGE_SIZE);
+       T_LOG("Killed child processes");
+}
+
+static proc_config_t
+spawn_child_processes(int child_count, child_action_handler_t child_handler)
+{
+       /*
+        * Spawn procs for Tests 1.2 and 1.3
+        */
+       T_LOG("Spawning child processes...");
+       proc_config_t proc_config = malloc(sizeof(*proc_config));
+       int action                = 0;
+       int err;
+
+       setpgid(0, 0);
+       proc_config->proc_grp_id = getpgid(0);
+
+       proc_config->child_count = child_count;
+
+       err = pipe(proc_config->parent_pipe);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(err, "pipe() call");
+
+       /*
+        * Needed for ACT_PHASE3 tests
+        */
+       proc_config->cow_map = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+       T_QUIET;
+       T_ASSERT_NE_PTR(proc_config->cow_map, MAP_FAILED, "cow_map mmap()");
+       *((int *)(proc_config->cow_map)) = 10;
+
+       pid_t child_pid;
+       int i;
+       int child_id;
+       for (i = 0; i < child_count; i++) {
+               err = pipe(proc_config->child_pipe[i]);
+               T_QUIET;
+               T_ASSERT_POSIX_SUCCESS(err, "pipe() call");
+
+               child_pid = fork();
+               child_id  = i;
+               T_QUIET;
+               T_ASSERT_POSIX_SUCCESS(child_pid, "fork() in parent process for child %d", child_id);
+
+               if (child_pid == 0) {
+                       child_handler(proc_config, child_id);
+               } else {
+                       proc_config->child_pids[child_id] = child_pid;
+               }
+               close(proc_config->child_pipe[child_id][PIPE_IN]);
+       }
+       /*
+        * Wait for the children processes to spawn
+        */
+       close(proc_config->parent_pipe[PIPE_OUT]);
+       WAIT_FOR_CHILDREN(proc_config->parent_pipe[PIPE_IN], action, child_count);
+
+       return proc_config;
+}
+
+/*
+ *  All PROC_INFO_CALL_PIDINFO __proc_info calls fire from this function.
+ *  T_DECLs require different combinations of structs and different actions
+ *  must occur in the child to get the data.  Instead of performing the setup
+ *  in each T_DECL, this function accepts a bitmap and performs the necessary setup
+ *  and cleanup work
+ */
+
+static void
+proc_info_caller(int proc_info_opts, void ** ret_structs, int * ret_child_pid)
+{
+       int retval, i = 0;
+       uint64_t * thread_addr = NULL;
+       void * map_tmp         = NULL;
+
+       proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
+       int child_pid             = proc_config->child_pids[0];
+       /*
+        * These tests only require one child.
+        * Some DECLs need to know the child pid, so we pass that back if applicable
+        */
+       if (ret_child_pid != NULL) {
+               *ret_child_pid = child_pid;
+       }
+
+       if (proc_info_opts & P_UNIQIDINFO) {
+               PROC_INFO_CALL(proc_uniqidentifierinfo, getpid(), PROC_PIDUNIQIDENTIFIERINFO, 0);
+       }
+       if (proc_info_opts & C_UNIQIDINFO) {
+               PROC_INFO_CALL(proc_uniqidentifierinfo, child_pid, PROC_PIDUNIQIDENTIFIERINFO, 0);
+       }
+       if (proc_info_opts & PBSD_OLD) {
+               PROC_INFO_CALL(proc_bsdinfo, child_pid, PROC_PIDTBSDINFO, 0);
+       }
+
+       /*
+        * Child Phase 2 Fires if opts require it
+        * Small nap after call to give child time to receive and execute the action
+        */
+
+       if (proc_info_opts >= PBSD) {
+               send_action_to_child_processes(proc_config, ACT_PHASE2);
+       }
+
+       if (proc_info_opts & PBSD) {
+               PROC_INFO_CALL(proc_bsdinfo, child_pid, PROC_PIDTBSDINFO, 0);
+       }
+
+       if (proc_info_opts & PBSD_SHORT) {
+               PROC_INFO_CALL(proc_bsdshortinfo, child_pid, PROC_PIDT_SHORTBSDINFO, 0);
+       }
+
+       if (proc_info_opts & PBSD_UNIQID) {
+               PROC_INFO_CALL(proc_bsdinfowithuniqid, child_pid, PROC_PIDT_BSDINFOWITHUNIQID, 0);
+       }
+       if (proc_info_opts & P_TASK_INFO) {
+               PROC_INFO_CALL(proc_taskinfo, child_pid, PROC_PIDTASKINFO, 0);
+       }
+
+       /*
+        * Child Phase 3 Fires
+        */
+       if (proc_info_opts >= P_TASK_INFO_NEW) {
+               send_action_to_child_processes(proc_config, ACT_PHASE3);
+       }
+
+       if (proc_info_opts & P_TASK_INFO_NEW) {
+               PROC_INFO_CALL(proc_taskinfo, child_pid, PROC_PIDTASKINFO, 0);
+       }
+
+       if (proc_info_opts & PALL) {
+               PROC_INFO_CALL(proc_taskallinfo, child_pid, PROC_PIDTASKALLINFO, 0);
+       }
+       /*
+        * This case breaks the pattern in that its proc_info call requires PALL,
+        * its value is required in some other proc_info calls
+        * and we never put the retval into our ret_structs
+        */
+       if (proc_info_opts & THREAD_ADDR || proc_info_opts & PTHINFO_OLD || proc_info_opts & PTHINFO || proc_info_opts & PINFO_PATH) {
+               struct proc_taskallinfo * pall = malloc(sizeof(struct proc_taskallinfo));
+               T_QUIET;
+               T_ASSERT_NOTNULL(pall, "malloc() for PROC_TASKALLINFO");
+
+               retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDTASKALLINFO, (uint32_t)0, (user_addr_t)pall,
+                                    (uint32_t)sizeof(struct proc_taskallinfo));
+               T_QUIET;
+               T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_taskallinfo), "__proc_info call for PROC_PIDTASKALLINFO in THREAD_ADDR");
+
+               thread_addr = malloc(sizeof(uint64_t) * (unsigned long)(pall->ptinfo.pti_threadnum + 1));
+               memset(thread_addr, 0, sizeof(uint64_t) * (unsigned long)(pall->ptinfo.pti_threadnum + 1));
+               T_QUIET;
+               T_ASSERT_NOTNULL(thread_addr, "malloc() for PROC_PIDLISTTHREADS");
+
+               retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDLISTTHREADS, (uint32_t)0, (user_addr_t)thread_addr,
+                                    (int32_t)(sizeof(uint64_t) * (unsigned long)(pall->ptinfo.pti_threadnum + 1)));
+               T_LOG("(int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE: %d",
+                     (int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE));
+               T_ASSERT_GE_INT((int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE), pall->ptinfo.pti_threadnum,
+                               "__proc_info call for PROC_PIDLISTTHREADS");
+
+               free(pall);
+       }
+       if (proc_info_opts & PTHINFO_OLD) {
+               PROC_INFO_CALL(proc_threadinfo, child_pid, PROC_PIDTHREADINFO, thread_addr[0]);
+       }
+
+       /*
+        * Child Phase 4 Fires
+        */
+       if (proc_info_opts >= PTHINFO) {
+               send_action_to_child_processes(proc_config, ACT_PHASE4);
+       }
+
+       if (proc_info_opts & PTHINFO) {
+               PROC_INFO_CALL(proc_threadinfo, child_pid, PROC_PIDTHREADINFO, thread_addr[0]);
+       }
+       if (proc_info_opts & PTHINFO_64) {
+               mach_port_name_t child_task  = MACH_PORT_NULL;
+               thread_array_t child_threads = NULL;
+               mach_msg_type_number_t child_thread_count;
+               thread_identifier_info_data_t child_thread_threadinfo;
+               mach_msg_type_number_t thread_info_count = THREAD_IDENTIFIER_INFO_COUNT;
+               struct proc_threadinfo * pthinfo_64      = malloc(sizeof(struct proc_threadinfo));
+               T_QUIET;
+               T_ASSERT_NOTNULL(pthinfo_64, "malloc() for PROC_THREADINFO");
+
+               retval = task_for_pid(mach_task_self(), child_pid, &child_task);
+               T_ASSERT_EQ_INT(retval, 0, "task_for_pid for PROC_PIDTHREADID64INFO");
+
+               retval = task_threads(child_task, &child_threads, &child_thread_count);
+               T_ASSERT_MACH_SUCCESS(retval, "task_threads() call for PROC_PIDTHREADID64INFO");
+
+               retval = thread_info(child_threads[0], THREAD_IDENTIFIER_INFO, (thread_info_t)&child_thread_threadinfo, &thread_info_count);
+               T_ASSERT_MACH_SUCCESS(retval, "thread_info call for PROC_PIDTHREADID64INFO");
+
+               retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDTHREADID64INFO, (uint64_t)child_thread_threadinfo.thread_id,
+                                    (user_addr_t)pthinfo_64, (uint32_t)sizeof(struct proc_threadinfo));
+               T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_threadinfo), "__proc_info call for PROC_PIDTHREADID64INFO");
+
+               ret_structs[i] = (void *)pthinfo_64;
+               i++;
+
+               mach_port_deallocate(mach_task_self(), child_task);
+               mach_port_deallocate(mach_task_self(), child_threads[0]);
+               child_threads[0] = MACH_PORT_NULL;
+               child_task       = MACH_PORT_NULL;
+       }
+       if (proc_info_opts & PINFO_PATH) {
+               PROC_INFO_CALL(proc_threadwithpathinfo, child_pid, PROC_PIDTHREADPATHINFO, thread_addr[0]);
+       }
+
+       if (proc_info_opts & PAI) {
+               PROC_INFO_CALL(proc_archinfo, getpid(), PROC_PIDARCHINFO, 0);
+       }
+
+       if ((proc_info_opts & PREGINFO) | (proc_info_opts & PREGINFO_PATH) | (proc_info_opts & PREGINFO_PATH_2) |
+           (proc_info_opts & PREGINFO_PATH_3)) {
+               tmp_fd = open(CONF_TMP_FILE_PATH, O_RDWR | O_CREAT);
+
+               for (int j = 0; j < 100; j++) {
+                       char buf[50];
+                       write(tmp_fd, buf, sizeof(buf));
+               }
+               retval = fsync(tmp_fd);
+               T_QUIET;
+               T_ASSERT_POSIX_SUCCESS(retval, "file fsync()");
+
+               map_tmp = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_PRIVATE, tmp_fd, (off_t)PAGE_SIZE);
+               T_ASSERT_NE_PTR(map_tmp, MAP_FAILED, "mmap() for PROC_PIDREGIONINFO");
+
+               T_LOG("file: %s is opened as fd %d and mapped at %llx with size %lu", CONF_TMP_FILE_PATH, tmp_fd, (uint64_t)map_tmp,
+                     (unsigned long)PAGE_SIZE);
+       }
+
+       if (proc_info_opts & PREGINFO) {
+               PROC_INFO_CALL(proc_regioninfo, getpid(), PROC_PIDREGIONINFO, map_tmp);
+               ret_structs[i] = map_tmp;
+               i++;
+       }
+       if (proc_info_opts & PREGINFO_PATH) {
+               PROC_INFO_CALL(proc_regionwithpathinfo, getpid(), PROC_PIDREGIONPATHINFO, map_tmp);
+               ret_structs[i] = map_tmp;
+               i++;
+       }
+       if (proc_info_opts & PREGINFO_PATH_2) {
+               PROC_INFO_CALL(proc_regionwithpathinfo, getpid(), PROC_PIDREGIONPATHINFO2, map_tmp);
+               ret_structs[i] = map_tmp;
+               i++;
+       }
+
+       if (proc_info_opts & PREGINFO_PATH_3) {
+               struct proc_regionwithpathinfo * preginfo_path = malloc(sizeof(struct proc_regionwithpathinfo));
+
+               retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDREGIONPATHINFO2, (uint64_t)map_tmp,
+                                    (user_addr_t)preginfo_path, (uint32_t)sizeof(struct proc_regionwithpathinfo));
+
+               T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_regionwithpathinfo), "__proc_info call for PROC_PIDREGIONPATHINFO2");
+
+               T_LOG("preginfo_path.prp_vip.vip_vi.vi_fsid.val 0: %d", preginfo_path->prp_vip.vip_vi.vi_fsid.val[0]);
+               T_LOG("preginfo_path.prp_vip.vip_vi.vi_fsid.val 1: %d", preginfo_path->prp_vip.vip_vi.vi_fsid.val[1]);
+
+               retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDREGIONPATHINFO3,
+                                    (uint64_t)(*(uint32_t *)(preginfo_path->prp_vip.vip_vi.vi_fsid.val)), (user_addr_t)preginfo_path,
+                                    (uint32_t)sizeof(struct proc_regionwithpathinfo));
+               T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_regionwithpathinfo), "__proc_info call for PROC_PIDREGIONPATHWITHINFO3");
+               ret_structs[i] = (void *)preginfo_path;
+               i++;
+       }
+
+       if (proc_info_opts & PVNINFO) {
+               PROC_INFO_CALL(proc_vnodepathinfo, getpid(), PROC_PIDVNODEPATHINFO, 0);
+       }
+
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+       free(thread_addr);
+       thread_addr = NULL;
+       close(tmp_fd);
+       tmp_fd = -1;
+}
+
+static void
+free_proc_info(void ** proc_info, int num)
+{
+       for (int i = 0; i < num; i++) {
+               free(proc_info[i]);
+       }
+
+       return;
+}
+
+/*
+ *     Start DECLs
+ */
+
+T_DECL(proc_info_listpids_all_pids,
+       "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       /*
+        * Get the value of nprocs with no buffer sent in
+        */
+       int num_procs;
+       num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)0, (uint32_t)0);
+       T_ASSERT_GE_INT(num_procs, 1, "verify valid value for nprocs: %d", num_procs);
+
+       proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
+
+       num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)0, (uint32_t)0);
+
+       int proc_count     = num_procs / (int)sizeof(pid_t);
+       int proc_count_all = num_procs / (int)sizeof(pid_t);
+       if (proc_count > (CONF_PROC_COUNT + 1)) {
+               proc_count = CONF_PROC_COUNT + 1;
+       }
+       pid_t * proc_ids = malloc(sizeof(pid_t) * (unsigned long)proc_count);
+       num_procs        = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
+                               (int32_t)(proc_count * (int)sizeof(pid_t)));
+       num_procs = num_procs / (int)sizeof(pid_t);
+       T_ASSERT_GE_INT(num_procs, proc_count, "Valid number of pids obtained for PROC_ALL_PIDS.");
+
+       free(proc_ids);
+
+       /*
+        * Grab list of all procs and make sure our spawned children are in the list.
+        */
+
+       proc_ids  = malloc(sizeof(pid_t) * (unsigned long)proc_count_all);
+       num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
+                               (int32_t)(proc_count_all * (int)sizeof(pid_t)));
+       num_procs = num_procs / (int)sizeof(pid_t);
+
+       int pid_match = 1;
+
+       for (int i = 0; i < (CONF_PROC_COUNT - 1); i++) {
+               for (int j = 0; j < num_procs; j++) {
+                       if (proc_ids[j] == proc_config->child_pids[i]) {
+                               break;
+                       } else if (j == (num_procs - 1)) {
+                               pid_match = 0;
+                               break;
+                       }
+               }
+
+               if (!pid_match) {
+                       break;
+               }
+       }
+
+       T_ASSERT_EQ(pid_match, 1, "PROC_INFO_CALL_LISTPIDS contains our spawned children's pids");
+
+       free(proc_ids);
+
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+
+       errno     = 0;
+       num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
+                               (uint32_t)(sizeof(pid_t) - 1));
+       T_EXPECT_POSIX_ERROR(errno, ENOMEM, "Valid proc_info behavior when bufsize < sizeof(pid_t).");
+}
+
+T_DECL(proc_info_listpids_pgrp_only,
+       "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
+       T_LOG("Test to verify PROC_PGRP_ONLY returns correct value");
+       /*
+        * The number of obtained pids depends on size of buffer.
+        * count = childCount + 1(parent)
+        * So, we set it to one more than expected to capture any error.
+        */
+       int proc_count   = CONF_PROC_COUNT + 2;
+       pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
+       int num_procs    = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_PGRP_ONLY, (uint32_t)proc_config->proc_grp_id, (uint32_t)0,
+                                   (user_addr_t)proc_ids, (int32_t)(proc_count * (int)sizeof(*proc_ids)));
+       num_procs = num_procs / (int)sizeof(pid_t);
+       T_ASSERT_EQ_INT(num_procs, CONF_PROC_COUNT + 1, "Valid number of pids obtained for PROC_PGRP_ONLY.");
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+       free(proc_ids);
+}
+
+T_DECL(proc_info_listpids_ppid_only,
+       "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
+       T_LOG("Test to verify PROC_PPID_ONLY returns correct value");
+       /*
+        * Pass in the same (bigger) buffer but expect only the pids where ppid is pid of current proc.
+        */
+       int proc_count   = CONF_PROC_COUNT + 2;
+       pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
+       int num_procs    = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_PPID_ONLY, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
+                                   (int32_t)(proc_count * (int)sizeof(*proc_ids)));
+       num_procs = num_procs / (int)sizeof(pid_t);
+       T_ASSERT_EQ_INT(num_procs, CONF_PROC_COUNT, "Valid number of pids obtained for PROC_PPID_ONLY.");
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+       free(proc_ids);
+}
+
+T_DECL(proc_info_listpids_uid_only,
+       "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
+       T_LOG("Test to verify PROC_UID_ONLY returns correct value");
+       int proc_count   = CONF_PROC_COUNT + 2;
+       pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
+       send_action_to_child_processes(proc_config, ACT_CHANGE_UID);
+       usleep(10000);
+       int num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_UID_ONLY, CONF_UID_VAL, (uint32_t)0, (user_addr_t)proc_ids,
+                                   (int32_t)(proc_count * (int)sizeof(*proc_ids)));
+       T_ASSERT_GE_ULONG((unsigned long)num_procs / sizeof(pid_t), (unsigned long)CONF_PROC_COUNT,
+                         "Valid number of pids obtained for PROC_UID_ONLY.");
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+       free(proc_ids);
+}
+
+T_DECL(proc_info_listpids_ruid_only,
+       "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
+       T_LOG("Test to verify PROC_RUID_ONLY returns correct value");
+       int proc_count   = CONF_PROC_COUNT + 2;
+       pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
+       send_action_to_child_processes(proc_config, ACT_CHANGE_RUID);
+       usleep(10000);
+       int num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_RUID_ONLY, CONF_RUID_VAL, (uint32_t)0, (user_addr_t)proc_ids,
+                                   (int32_t)(proc_count * (int)sizeof(*proc_ids)));
+       T_ASSERT_GE_ULONG((unsigned long)num_procs / sizeof(pid_t), (unsigned long)CONF_PROC_COUNT,
+                         "Valid number of pids obtained for PROC_RUID_ONLY.");
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+       free(proc_ids);
+}
+
+T_DECL(proc_info_listpids_tty_only,
+       "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       int ret = isatty(STDOUT_FILENO);
+       if (ret != 1) {
+               T_SKIP("Not connected to tty...skipping test");
+       }
+
+       proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
+
+       T_LOG("Test to verify PROC_TTY_ONLY returns correct value");
+       int proc_count   = CONF_PROC_COUNT + 2;
+       pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
+       int num_procs    = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_TTY_ONLY, get_tty_dev(), (uint32_t)0, (user_addr_t)proc_ids,
+                                   (int32_t)(proc_count * (int)sizeof(*proc_ids)));
+       num_procs = num_procs / (int)sizeof(pid_t);
+       T_ASSERT_GE_INT(num_procs, 0, "Valid number of pids returned by PROC_TTY_ONLY.");
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+       free(proc_ids);
+}
+
+/*
+ * Most of the following PROC_INFO_CALL_PIDINFO tests rely on a helper function (proc_info_caller) to make the necessary proc_info
+ * calls on their behalf
+ * In a previous iteration, these tests were all in one giant T_DECL and the helper function handles inter-DECL dependencies such as
+ * a proc_info call relying on the results of a previous proc_info call or an assumed state that a child should be in.
+ */
+
+T_DECL(proc_info_pidinfo_proc_piduniqidentifierinfo,
+       "Test to identify PROC_PIDUNIQIDENTIFIERINFO returns correct unique identifiers for process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       proc_info_caller(P_UNIQIDINFO | C_UNIQIDINFO, proc_info, NULL);
+       struct proc_uniqidentifierinfo * p_uniqidinfo = (struct proc_uniqidentifierinfo *)proc_info[0];
+       struct proc_uniqidentifierinfo * c_uniqidinfo = (struct proc_uniqidentifierinfo *)proc_info[1];
+
+       T_EXPECT_NE_ULLONG(c_uniqidinfo->p_uniqueid, p_uniqidinfo->p_uniqueid, "p_uniqueid not unique for the process");
+
+       for (size_t i = 0; i < 16; i++) {
+               T_EXPECT_EQ_UCHAR(c_uniqidinfo->p_uuid[i], p_uniqidinfo->p_uuid[i], "p_uuid should be the same unique id");
+       }
+       T_EXPECT_EQ_ULLONG(c_uniqidinfo->p_puniqueid, p_uniqidinfo->p_uniqueid,
+                          "p_puniqueid of child should be same as p_uniqueid for parent");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_pidinfo_proc_pidtbsdinfo,
+       "Test to verify PROC_PIDTBSDINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       int child_pid = 0;
+       proc_info_caller(PBSD_OLD | PBSD, proc_info, &child_pid);
+       struct proc_bsdinfo * pbsd_old = (struct proc_bsdinfo *)proc_info[0];
+       struct proc_bsdinfo * pbsd     = (struct proc_bsdinfo *)proc_info[1];
+
+       T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd->pbi_status, "PROC_PIDTBSDINFO shows Correct status");
+       T_EXPECT_EQ_UINT(0U, pbsd->pbi_xstatus, "PROC_PIDTBSDINFO show Correct xstatus (exit status)");
+       T_EXPECT_EQ_UINT(pbsd->pbi_pid, (unsigned int)child_pid, "PROC_PIDTBSDINFO returns valid pid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_ppid, (unsigned int)getpid(), "PROC_PIDTBSDINFO returns valid ppid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_uid, CONF_RUID_VAL, "PROC_PIDTBSDINFO returns valid uid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_gid, CONF_GID_VAL, "PROC_PIDTBSDINFO returns valid gid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_ruid, 0U, "PROC_PIDTBSDINFO returns valid ruid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_rgid, CONF_GID_VAL, "PROC_PIDTBSDINFO returns valid rgid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_svuid, CONF_RUID_VAL, "PROC_PIDTBSDINFO returns valid svuid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_svgid, CONF_GID_VAL, "PROC_PIDTBSDINFO returns valid svgid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_nice, CONF_NICE_VAL, "PROC_PIDTBSDINFO returns valid nice value");
+       T_EXPECT_EQ_STR(pbsd->pbi_comm, CONF_CMD_NAME, "PROC_PIDTBSDINFO returns valid p_comm name");
+       T_EXPECT_EQ_STR(pbsd->pbi_name, CONF_CMD_NAME, "PROC_PIDTBSDINFO returns valid p_name name");
+       T_EXPECT_EQ_UINT(pbsd->pbi_flags, (pbsd_old->pbi_flags | PROC_FLAG_PSUGID), "PROC_PIDTBSDINFO returns valid flags");
+       T_EXPECT_EQ_UINT(pbsd->pbi_nfiles, pbsd_old->pbi_nfiles, "PROC_PIDTBSDINFO returned valid pbi_nfiles");
+       T_EXPECT_EQ_UINT(pbsd->pbi_pgid, (uint32_t)getpgid(getpid()), "PROC_PIDTBSDINFO returned valid pbi_pgid");
+       T_EXPECT_EQ_UINT(pbsd->pbi_pjobc, pbsd->pbi_pjobc, "PROC_PIDTBSDINFO returned valid pbi_pjobc");
+       T_EXPECT_NE_UINT(pbsd->e_tdev, 0U, "PROC_PIDTBSDINFO returned valid e_tdev");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_pidt_shortbsdinfo,
+       "Test to verify PROC_PIDT_SHORTBSDINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       int child_pid = 0;
+       proc_info_caller(PBSD | PBSD_SHORT, proc_info, &child_pid);
+       struct proc_bsdinfo * pbsd            = (struct proc_bsdinfo *)proc_info[0];
+       struct proc_bsdshortinfo * pbsd_short = (struct proc_bsdshortinfo *)proc_info[1];
+
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_pid, (unsigned int)child_pid, "PROC_PIDT_SHORTBSDINFO returns valid pid");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_ppid, (unsigned int)getpid(), "PROC_PIDT_SHORTBSDINFO returns valid ppid");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_pgid, (uint32_t)getpgid(getpid()), "PROC_PIDT_SHORTBSDINFO returned valid pbi_pgid");
+       T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd_short->pbsi_status, "PROC_PIDT_SHORTBSDINFO shows Correct status");
+       T_EXPECT_EQ_STR(pbsd_short->pbsi_comm, CONF_CMD_NAME, "PROC_PIDT_SHORTBSDINFO returns valid p_comm name");
+       /*
+        * The short variant returns all flags except session flags, hence ignoring them here.
+        */
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_flags, (pbsd->pbi_flags & (unsigned int)(~PROC_FLAG_CTTY)),
+                        "PROC_PIDT_SHORTBSDINFO returns valid flags");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_uid, CONF_RUID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid uid");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_gid, CONF_GID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid gid");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_ruid, 0U, "PROC_PIDT_SHORTBSDINFO returns valid ruid");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_svuid, CONF_RUID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid svuid");
+       T_EXPECT_EQ_UINT(pbsd_short->pbsi_svgid, CONF_GID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid svgid");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_pidt_bsdinfowithuniqid,
+       "Test to verify PROC_PIDT_BSDINFOWITHUNIQID returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[4];
+       int child_pid = 0;
+       proc_info_caller(P_UNIQIDINFO | PBSD_OLD | PBSD | PBSD_UNIQID, proc_info, &child_pid);
+       struct proc_uniqidentifierinfo * p_uniqidinfo = (struct proc_uniqidentifierinfo *)proc_info[0];
+       struct proc_bsdinfo * pbsd_old                = (struct proc_bsdinfo *)proc_info[1];
+       struct proc_bsdinfo * pbsd                    = (struct proc_bsdinfo *)proc_info[2];
+       struct proc_bsdinfowithuniqid * pbsd_uniqid   = (struct proc_bsdinfowithuniqid *)proc_info[3];
+
+       T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd->pbi_status, "PROC_PIDT_BSDINFOWITHUNIQID shows Correct status");
+       T_EXPECT_EQ_UINT(0U, pbsd->pbi_xstatus, "PROC_PIDT_BSDINFOWITHUNIQID show Correct xstatus");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_pid, (unsigned int)child_pid, "PROC_PIDT_BSDINFOWITHUNIQID returns valid pid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_ppid, (unsigned int)getpid(), "PROC_PIDT_BSDINFOWITHUNIQID returns valid ppid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_uid, CONF_RUID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid uid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_gid, CONF_GID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid gid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_ruid, 0U, "PROC_PIDT_BSDINFOWITHUNIQID returns valid ruid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_rgid, CONF_GID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid rgid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_svuid, CONF_RUID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid svuid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_svgid, CONF_GID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid svgid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_nice, CONF_NICE_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid nice value");
+       T_EXPECT_EQ_STR(pbsd_uniqid->pbsd.pbi_comm, CONF_CMD_NAME, "PROC_PIDT_BSDINFOWITHUNIQID returns valid p_comm name");
+       T_EXPECT_EQ_STR(pbsd_uniqid->pbsd.pbi_name, CONF_CMD_NAME, "PROC_PIDT_BSDINFOWITHUNIQID returns valid p_name name");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_flags, (pbsd_old->pbi_flags | PROC_FLAG_PSUGID),
+                        "PROC_PIDT_BSDINFOWITHUNIQID returns valid flags");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_nfiles, pbsd_old->pbi_nfiles, "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_nfiles");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_pgid, (uint32_t)getpgid(getpid()),
+                        "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_pgid");
+       T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_pjobc, pbsd->pbi_pjobc, "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_pjobc");
+       T_EXPECT_NE_UINT(pbsd_uniqid->pbsd.e_tdev, 0U, "PROC_PIDT_BSDINFOWITHUNIQID returned valid e_tdev");
+       T_EXPECT_NE_ULLONG(pbsd_uniqid->p_uniqidentifier.p_uniqueid, p_uniqidinfo->p_uniqueid,
+                          "PROC_PIDT_BSDINFOWITHUNIQID returned valid p_uniqueid");
+       for (int i = 0; i < 16; i++) {
+               T_EXPECT_EQ_UCHAR(pbsd_uniqid->p_uniqidentifier.p_uuid[i], p_uniqidinfo->p_uuid[i],
+                                 "PROC_PIDT_BSDINFOWITHUNIQID reported valid p_uniqueid");
+       }
+       T_EXPECT_EQ_ULLONG(pbsd_uniqid->p_uniqidentifier.p_puniqueid, p_uniqidinfo->p_uniqueid,
+                          "p_puniqueid of child should be same as p_uniqueid for parent");
+
+       free_proc_info(proc_info, 4);
+}
+
+T_DECL(proc_info_proc_pidtask_info,
+       "Test to verify PROC_PIDTASKINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       proc_info_caller(P_TASK_INFO | P_TASK_INFO_NEW, proc_info, NULL);
+       struct proc_taskinfo * p_task_info     = (struct proc_taskinfo *)proc_info[0];
+       struct proc_taskinfo * p_task_info_new = (struct proc_taskinfo *)proc_info[1];
+
+       T_EXPECT_GE_ULLONG((p_task_info_new->pti_virtual_size - p_task_info->pti_virtual_size), (unsigned long long)PAGE_SIZE,
+                          "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
+       T_EXPECT_GE_ULLONG((p_task_info_new->pti_resident_size - p_task_info->pti_resident_size), (unsigned long long)PAGE_SIZE,
+                          "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
+       T_EXPECT_EQ_INT(p_task_info_new->pti_policy, POLICY_TIMESHARE, "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
+       T_EXPECT_GE_ULLONG(p_task_info->pti_threads_user, 1ULL, "PROC_PIDTASKINFO returned valid value for pti_threads_user");
+#if defined(__arm__) || defined(__arm64__)
+       T_EXPECT_GE_ULLONG(p_task_info->pti_threads_system, 0ULL, "PROC_PIDTASKINFO returned valid value for pti_threads_system");
+       T_EXPECT_GE_ULLONG((p_task_info_new->pti_total_system - p_task_info->pti_total_system), 0ULL,
+                          "PROC_PIDTASKINFO returned valid value for pti_total_system");
+#else
+       T_EXPECT_GE_ULLONG(p_task_info->pti_threads_system, 1ULL, "PROC_PIDTASKINFO returned valid value for pti_threads_system");
+       T_EXPECT_GT_ULLONG((p_task_info_new->pti_total_system - p_task_info->pti_total_system), 0ULL,
+                          "PROC_PIDTASKINFO returned valid value for pti_total_system");
+#endif
+       T_EXPECT_GT_ULLONG((p_task_info_new->pti_total_user - p_task_info->pti_total_user), 0ULL,
+                          "PROC_PIDTASKINFO returned valid value for pti_total_user");
+       T_EXPECT_GE_INT((p_task_info_new->pti_faults - p_task_info->pti_faults), 1,
+                       "PROC_PIDTASKINFO returned valid value for pti_faults");
+       T_EXPECT_GE_INT((p_task_info_new->pti_cow_faults - p_task_info->pti_cow_faults), 1,
+                       "PROC_PIDTASKINFO returned valid value for pti_cow_faults");
+       T_EXPECT_GE_INT((p_task_info_new->pti_syscalls_mach - p_task_info->pti_syscalls_mach), 0,
+                       "PROC_PIDTASKINFO returned valid value for pti_syscalls_mach");
+       T_EXPECT_GE_INT((p_task_info_new->pti_syscalls_unix - p_task_info->pti_syscalls_unix), 2,
+                       "PROC_PIDTASKINFO returned valid value for pti_syscalls_unix");
+       T_EXPECT_EQ_INT((p_task_info_new->pti_messages_sent - p_task_info->pti_messages_sent), 0,
+                       "PROC_PIDTASKINFO returned valid value for pti_messages_sent");
+       T_EXPECT_EQ_INT((p_task_info_new->pti_messages_received - p_task_info->pti_messages_received), 0,
+                       "PROC_PIDTASKINFO returned valid value for pti_messages_received");
+       T_EXPECT_EQ_INT(p_task_info_new->pti_priority, p_task_info->pti_priority,
+                       "PROC_PIDTASKINFO returned valid value for pti_priority");
+       T_EXPECT_GE_INT(p_task_info_new->pti_threadnum, 1, "PROC_PIDTASKINFO returned valid value for pti_threadnum");
+
+       if (p_task_info_new->pti_threadnum > 1) {
+               T_LOG("WARN: PROC_PIDTASKINFO returned threadnum greater than 1");
+       }
+       T_EXPECT_GE_INT(p_task_info_new->pti_numrunning, 0, "PROC_PIDTASKINFO returned valid value for pti_numrunning");
+       T_EXPECT_GE_INT(p_task_info_new->pti_pageins, 0, "PROC_PIDTASKINFO returned valid value for pti_pageins");
+
+       if (p_task_info_new->pti_pageins > 0) {
+               T_LOG("WARN: PROC_PIDTASKINFO returned pageins greater than 0");
+       }
+
+       T_EXPECT_GE_INT(p_task_info_new->pti_csw, p_task_info->pti_csw, "PROC_PIDTASKINFO returned valid value for pti_csw");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_proc_pidtaskallinfo,
+       "Test to verify PROC_PIDTASKALLINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[4];
+       int child_pid = 0;
+       proc_info_caller(PBSD | PBSD_OLD | P_TASK_INFO | PALL, proc_info, &child_pid);
+       struct proc_bsdinfo * pbsd         = (struct proc_bsdinfo *)proc_info[0];
+       struct proc_bsdinfo * pbsd_old     = (struct proc_bsdinfo *)proc_info[1];
+       struct proc_taskinfo * p_task_info = (struct proc_taskinfo *)proc_info[2];
+       struct proc_taskallinfo * pall     = (struct proc_taskallinfo *)proc_info[3];
+
+       T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd->pbi_status, "PROC_PIDTASKALLINFO shows Correct status");
+       T_EXPECT_EQ_UINT(0U, pbsd->pbi_xstatus, "PROC_PIDTASKALLINFO show Correct xstatus");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_pid, (unsigned int)child_pid, "PROC_PIDTASKALLINFO returns valid pid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_ppid, (unsigned int)getpid(), "PROC_PIDTASKALLINFO returns valid ppid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_uid, CONF_RUID_VAL, "PROC_PIDTASKALLINFO returns valid uid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_gid, CONF_GID_VAL, "PROC_PIDTASKALLINFO returns valid gid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_ruid, 0U, "PROC_PIDTASKALLINFO returns valid ruid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_rgid, CONF_GID_VAL, "PROC_PIDTASKALLINFO returns valid rgid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_svuid, CONF_RUID_VAL, "PROC_PIDTASKALLINFO returns valid svuid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_svgid, CONF_GID_VAL, "PROC_PIDTASKALLINFO returns valid svgid");
+       T_EXPECT_EQ_INT(pall->pbsd.pbi_nice, CONF_NICE_VAL, "PROC_PIDTASKALLINFO returns valid nice value");
+       T_EXPECT_EQ_STR(pall->pbsd.pbi_comm, CONF_CMD_NAME, "PROC_PIDTASKALLINFO returns valid p_comm name");
+       T_EXPECT_EQ_STR(pall->pbsd.pbi_name, CONF_CMD_NAME, "PROC_PIDTASKALLINFO returns valid p_name name");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_flags, (pbsd_old->pbi_flags | PROC_FLAG_PSUGID), "PROC_PIDTASKALLINFO returns valid flags");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_nfiles, pbsd_old->pbi_nfiles, "PROC_PIDTASKALLINFO returned valid pbi_nfiles");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_pgid, (uint32_t)getpgid(getpid()), "PROC_PIDTASKALLINFO returned valid pbi_pgid");
+       T_EXPECT_EQ_UINT(pall->pbsd.pbi_pjobc, pbsd->pbi_pjobc, "PROC_PIDTASKALLINFO returned valid pbi_pjobc");
+       T_EXPECT_NE_UINT(pall->pbsd.e_tdev, 0U, "PROC_PIDTASKALLINFO returned valid e_tdev");
+
+#if defined(__arm__) || defined(__arm64__)
+       T_EXPECT_GE_ULLONG(pall->ptinfo.pti_threads_system, 0ULL, "PROC_PIDTASKALLINFO returned valid value for pti_threads_system");
+       T_EXPECT_GE_ULLONG((pall->ptinfo.pti_total_system - p_task_info->pti_total_system), 0ULL,
+                          "PROC_PIDTASKALLINFO returned valid value for pti_total_system");
+#else
+       T_EXPECT_GE_ULLONG(pall->ptinfo.pti_threads_system, 1ULL, "PROC_PIDTASKALLINFO returned valid value for pti_threads_system");
+       T_EXPECT_GT_ULLONG((pall->ptinfo.pti_total_system - p_task_info->pti_total_system), 0ULL,
+                          "PROC_PIDTASKALLINFO returned valid value for pti_total_system");
+#endif /* ARM */
+
+       T_EXPECT_GE_ULLONG((pall->ptinfo.pti_virtual_size - p_task_info->pti_virtual_size), (unsigned long long)PAGE_SIZE,
+                          "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
+       T_EXPECT_GE_ULLONG((pall->ptinfo.pti_resident_size - p_task_info->pti_resident_size), (unsigned long long)PAGE_SIZE,
+                          "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
+       T_EXPECT_EQ_INT(pall->ptinfo.pti_policy, POLICY_TIMESHARE, "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
+       T_EXPECT_GE_ULLONG(pall->ptinfo.pti_threads_user, 1ULL, "PROC_PIDTASKALLINFO returned valid value for pti_threads_user ");
+       T_EXPECT_GT_ULLONG((pall->ptinfo.pti_total_user - p_task_info->pti_total_user), 0ULL,
+                          "PROC_PIDTASKALLINFO returned valid value for pti_total_user");
+       T_EXPECT_GE_INT((pall->ptinfo.pti_faults - p_task_info->pti_faults), 1,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_faults");
+       T_EXPECT_GE_INT((pall->ptinfo.pti_cow_faults - p_task_info->pti_cow_faults), 1,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_cow_faults");
+       T_EXPECT_GE_INT((pall->ptinfo.pti_syscalls_mach - p_task_info->pti_syscalls_mach), 0,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_syscalls_mach");
+       T_EXPECT_GE_INT((pall->ptinfo.pti_syscalls_unix - p_task_info->pti_syscalls_unix), 2,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_syscalls_unix");
+       T_EXPECT_EQ_INT((pall->ptinfo.pti_messages_sent - p_task_info->pti_messages_sent), 0,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_messages_sent");
+       T_EXPECT_EQ_INT((pall->ptinfo.pti_messages_received - p_task_info->pti_messages_received), 0,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_messages_received");
+       T_EXPECT_EQ_INT(pall->ptinfo.pti_priority, p_task_info->pti_priority,
+                       "PROC_PIDTASKALLINFO returned valid value for pti_priority");
+       T_EXPECT_GE_INT(pall->ptinfo.pti_threadnum, 1, "PROC_PIDTASKALLINFO returned valid value for pti_threadnum");
+       if (pall->ptinfo.pti_threadnum > 1) {
+               T_LOG("WARN: PROC_PIDTASKALLINFO returned threadnum greater than 1");
+       }
+       T_EXPECT_GE_INT(pall->ptinfo.pti_numrunning, 0, "PROC_PIDTASKALLINFO returned valid value for pti_numrunning");
+       T_EXPECT_GE_INT(pall->ptinfo.pti_pageins, 0, "PROC_PIDTASKALLINFO returned valid value for pti_pageins");
+       if (pall->ptinfo.pti_pageins > 0) {
+               T_LOG("WARN: PROC_PIDTASKALLINFO returned pageins greater than 0");
+       }
+       T_EXPECT_GE_INT(pall->ptinfo.pti_csw, p_task_info->pti_csw, "PROC_PIDTASKALLINFO returned valid value for pti_csw");
+
+       free_proc_info(proc_info, 4);
+}
+
+T_DECL(proc_info_proc_pidlistthreads,
+       "Test to verify PROC_PIDLISTTHREADS returns valid information about process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[1];
+       proc_info_caller(THREAD_ADDR, proc_info, NULL);
+}
+
+T_DECL(proc_info_proc_pidthreadinfo,
+       "Test to verify PROC_PIDTHREADINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       int child_pid = 0;
+       proc_info_caller(PTHINFO_OLD | PTHINFO, proc_info, &child_pid);
+       struct proc_threadinfo * pthinfo_old = (struct proc_threadinfo *)proc_info[0];
+       struct proc_threadinfo * pthinfo     = (struct proc_threadinfo *)proc_info[1];
+
+       T_EXPECT_GT_ULLONG((pthinfo->pth_user_time - pthinfo_old->pth_user_time), 0ULL,
+                          "PROC_PIDTHREADINFO returns valid value for pth_user_time");
+       T_EXPECT_GE_ULLONG((pthinfo->pth_system_time - pthinfo_old->pth_system_time), 0ULL,
+                          "PROC_PIDTHREADINFO returns valid value for pth_system_time");
+       /*
+        * This is the scaled cpu usage percentage, since we are not
+        * doing a really long CPU bound task, it is (nearly) zero
+        */
+       T_EXPECT_GE_INT(pthinfo->pth_cpu_usage, 0, "PROC_PIDTHREADINFO returns valid value for pth_cpu_usage");
+       T_EXPECT_EQ_INT(pthinfo->pth_policy, POLICY_TIMESHARE, "PROC_PIDTHREADINFO returns valid value for pth_policy");
+       if (!(pthinfo->pth_run_state == TH_STATE_WAITING) && !(pthinfo->pth_run_state == TH_STATE_RUNNING)) {
+               T_EXPECT_EQ_INT(pthinfo->pth_run_state, -1, "PROC_PIDTHREADINFO returns valid value for pth_run_state");
+       }
+       /*
+        * This value is hardcoded to 0 in the source, hence it will always
+        * unconditionally return 0
+        */
+       T_EXPECT_EQ_INT(pthinfo->pth_sleep_time, 0, "PROC_PIDTHREADINFO returns valid value for pth_sleep_time");
+       T_EXPECT_LE_INT(pthinfo->pth_curpri, (BASEPRI_DEFAULT - CONF_NICE_VAL),
+                       "PROC_PIDTHREADINFO returns valid value for pth_curpri");
+       T_EXPECT_EQ_INT(pthinfo->pth_priority, (BASEPRI_DEFAULT - CONF_NICE_VAL),
+                       "PROC_PIDTHREADINFO returns valid value for pth_priority");
+       T_EXPECT_EQ_INT(pthinfo->pth_maxpriority, MAXPRI_USER, "PROC_PIDTHREADINFO returns valid value for pth_maxpriority");
+       T_EXPECT_EQ_STR(pthinfo->pth_name, CONF_THREAD_NAME, "PROC_PIDTHREADINFO returns valid value for pth_name");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_proc_threadid64info,
+       "Test to verify PROC_PIDTHREADID64INFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       proc_info_caller(PTHINFO | PTHINFO_64, proc_info, NULL);
+       struct proc_threadinfo pthinfo    = *((struct proc_threadinfo *)proc_info[0]);
+       struct proc_threadinfo pthinfo_64 = *((struct proc_threadinfo *)proc_info[1]);
+       T_EXPECT_GE_ULLONG(pthinfo_64.pth_user_time, pthinfo.pth_user_time,
+                          "PROC_PIDTHREADID64INFO returns valid value for pth_user_time");
+       T_EXPECT_GE_ULLONG(pthinfo_64.pth_system_time, pthinfo.pth_system_time,
+                          "PROC_PIDTHREADID64INFO returns valid value for pth_system_time");
+       T_EXPECT_GE_INT(pthinfo_64.pth_cpu_usage, pthinfo.pth_cpu_usage,
+                       "PROC_PIDTHREADID64INFO returns valid value for pth_cpu_usage");
+       T_EXPECT_EQ_INT(pthinfo_64.pth_policy, POLICY_TIMESHARE, "PROC_PIDTHREADID64INFO returns valid value for pth_policy");
+       if (!(pthinfo_64.pth_run_state == TH_STATE_WAITING) && !(pthinfo_64.pth_run_state == TH_STATE_RUNNING)) {
+               T_EXPECT_EQ_INT(pthinfo_64.pth_run_state, -1, "PROC_PIDTHREADID64INFO returns valid value for pth_run_state");
+       }
+       T_EXPECT_EQ_INT(pthinfo_64.pth_sleep_time, 0, "PROC_PIDTHREADID64INFO returns valid value for pth_sleep_time");
+       T_EXPECT_EQ_INT(pthinfo_64.pth_curpri, pthinfo.pth_curpri, "PROC_PIDTHREADID64INFO returns valid value for pth_curpri");
+       T_EXPECT_EQ_INT(pthinfo_64.pth_priority, pthinfo.pth_priority, "PROC_PIDTHREADID64INFO returns valid value for pth_priority");
+       T_EXPECT_EQ_INT(pthinfo_64.pth_maxpriority, pthinfo.pth_maxpriority,
+                       "PROC_PIDTHREADID64INFO returns valid value for pth_maxpriority");
+       T_EXPECT_EQ_STR(pthinfo_64.pth_name, CONF_THREAD_NAME, "PROC_PIDTHREADID64INFO returns valid value for pth_name");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_proc_pidthreadpathinfo,
+       "Test to verify PROC_PIDTHREADPATHINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       proc_info_caller(PTHINFO | PINFO_PATH, proc_info, NULL);
+       struct proc_threadinfo pthinfo            = *((struct proc_threadinfo *)proc_info[0]);
+       struct proc_threadwithpathinfo pinfo_path = *((struct proc_threadwithpathinfo *)proc_info[1]);
+
+       T_EXPECT_GE_ULLONG(pinfo_path.pt.pth_user_time, pthinfo.pth_user_time,
+                          "PROC_PIDTHREADPATHINFO returns valid value for pth_user_time");
+       T_EXPECT_GE_ULLONG(pinfo_path.pt.pth_system_time, pthinfo.pth_system_time,
+                          "PROC_PIDTHREADPATHINFO returns valid value for pth_system_time");
+       T_EXPECT_GE_INT(pinfo_path.pt.pth_cpu_usage, pthinfo.pth_cpu_usage,
+                       "PROC_PIDTHREADPATHINFO returns valid value for pth_cpu_usage");
+       T_EXPECT_EQ_INT(pinfo_path.pt.pth_policy, POLICY_TIMESHARE, "PROC_PIDTHREADPATHINFO returns valid value for pth_policy");
+       if (!(pinfo_path.pt.pth_run_state == TH_STATE_WAITING) && !(pinfo_path.pt.pth_run_state == TH_STATE_RUNNING)) {
+               T_EXPECT_EQ_INT(pinfo_path.pt.pth_run_state, -1, "PROC_PIDTHREADPATHINFO returns valid value for pth_run_state");
+       }
+       T_EXPECT_EQ_INT(pinfo_path.pt.pth_sleep_time, 0, "PROC_PIDTHREADPATHINFO returns valid value for pth_sleep_time");
+       T_EXPECT_EQ_INT(pinfo_path.pt.pth_curpri, pthinfo.pth_curpri, "PROC_PIDTHREADPATHINFO returns valid value for pth_curpri");
+       T_EXPECT_EQ_INT(pinfo_path.pt.pth_priority, pthinfo.pth_priority,
+                       "PROC_PIDTHREADPATHINFO returns valid value for pth_priority");
+       T_EXPECT_EQ_INT(pinfo_path.pt.pth_maxpriority, pthinfo.pth_maxpriority,
+                       "PROC_PIDTHREADPATHINFO returns valid value for pth_maxpriority");
+       T_EXPECT_EQ_STR(pinfo_path.pt.pth_name, CONF_THREAD_NAME, "PROC_PIDTHREADPATHINFO returns valid value for pth_name");
+       T_EXPECT_EQ_INT(pinfo_path.pvip.vip_vi.vi_type, VNON, "PROC_PIDTHREADPATHINFO valid vnode information");
+
+       free_proc_info(proc_info, 2);
+}
+
+T_DECL(proc_info_proc_pidarchinfo,
+       "Test to verify PROC_PIDARCHINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[1];
+       proc_info_caller(PAI, proc_info, NULL);
+       struct proc_archinfo pai = *((struct proc_archinfo *)proc_info[0]);
+
+#if defined(__arm__) || defined(__arm64__)
+       if (!((pai.p_cputype & CPU_TYPE_ARM) == CPU_TYPE_ARM) && !((pai.p_cputype & CPU_TYPE_ARM64) == CPU_TYPE_ARM64)) {
+               T_EXPECT_EQ_INT(pai.p_cputype, CPU_TYPE_ARM, "PROC_PIDARCHINFO returned valid value for p_cputype");
+       }
+       T_EXPECT_EQ_INT((pai.p_cpusubtype & CPU_SUBTYPE_ARM_ALL), CPU_SUBTYPE_ARM_ALL,
+                       "PROC_PIDARCHINFO returned valid value for p_cpusubtype");
+#else
+       if (!((pai.p_cputype & CPU_TYPE_X86) == CPU_TYPE_X86) && !((pai.p_cputype & CPU_TYPE_X86_64) == CPU_TYPE_X86_64)) {
+               T_EXPECT_EQ_INT(pai.p_cputype, CPU_TYPE_X86, "PROC_PIDARCHINFO returned valid value for p_cputype");
+       }
+#endif
+       free_proc_info(proc_info, 1);
+}
+
+T_DECL(proc_info_proc_pidregioninfo,
+       "Test to verify PROC_PIDREGIONINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[2];
+       void * map_tmp = NULL;
+       proc_info_caller(PREGINFO, proc_info, NULL);
+
+       struct proc_regioninfo preginfo = *((struct proc_regioninfo *)proc_info[0]);
+       /*
+        *      map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
+        */
+       map_tmp = proc_info[1];
+
+       T_EXPECT_EQ_ULLONG(preginfo.pri_offset, (unsigned long long)PAGE_SIZE, "PROC_PIDREGIONINFO returns valid value for pri_offset");
+       T_EXPECT_EQ_UINT((preginfo.pri_protection ^ (VM_PROT_READ | VM_PROT_WRITE)), 0U,
+                        "PROC_PIDREGIONINFO returns valid value for pri_protection, expected read/write only");
+       T_EXPECT_EQ_UINT((preginfo.pri_max_protection & (VM_PROT_READ | VM_PROT_WRITE)), (unsigned int)(VM_PROT_READ | VM_PROT_WRITE),
+                        "PROC_PIDREGIONINFO returns valid value for pri_max_protection");
+       T_EXPECT_EQ_UINT((preginfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
+                        "PROC_PIDREGIONINFO returns valid value for pri_inheritance");
+       T_EXPECT_EQ_UINT((preginfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U, "PROC_PIDREGIONINFO returns valid value for pri_behavior");
+       T_EXPECT_EQ_UINT(preginfo.pri_user_wired_count, 0U, "PROC_PIDREGIONINFO returns valid value for pri_user_wired_count");
+       T_EXPECT_EQ_UINT(preginfo.pri_user_tag, 0U, "PROC_PIDREGIONINFO returns valid value for pri_user_tag");
+       T_EXPECT_NE_UINT((preginfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
+                        "PROC_PIDREGIONINFO returns valid value for pri_flags");
+       T_EXPECT_EQ_UINT(preginfo.pri_pages_resident, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_resident");
+       T_EXPECT_EQ_UINT(preginfo.pri_pages_shared_now_private, 0U,
+                        "PROC_PIDREGIONINFO returns valid value for pri_pages_shared_now_private");
+       T_EXPECT_EQ_UINT(preginfo.pri_pages_swapped_out, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_swapped_out");
+       T_EXPECT_EQ_UINT(preginfo.pri_pages_dirtied, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_dirtied");
+       T_EXPECT_EQ_UINT(preginfo.pri_ref_count, 2U, "PROC_PIDREGIONINFO returns valid value for pri_ref_count");
+       T_EXPECT_EQ_UINT(preginfo.pri_shadow_depth, 1U, "PROC_PIDREGIONINFO returns valid value for pri_shadow_depth");
+       T_EXPECT_EQ_UINT(preginfo.pri_share_mode, (unsigned int)SM_COW, "PROC_PIDREGIONINFO returns valid value for pri_share_mode");
+       T_EXPECT_EQ_UINT(preginfo.pri_private_pages_resident, 0U,
+                        "PROC_PIDREGIONINFO returns valid value for pri_private_pages_resident");
+       T_EXPECT_GE_UINT(preginfo.pri_shared_pages_resident, 1U,
+                        "PROC_PIDREGIONINFO returns valid value for pri_shared_pages_resident");
+       T_EXPECT_EQ_ULLONG(preginfo.pri_address, (uint64_t)map_tmp, "PROC_PIDREGIONINFO returns valid value for pri_addr");
+       T_EXPECT_NE_UINT(preginfo.pri_obj_id, 0U, "PROC_PIDREGIONINFO returns valid value for pri_obj_id");
+       T_EXPECT_EQ_ULLONG(preginfo.pri_size, (unsigned long long)PAGE_SIZE, "PROC_PIDREGIONINFO returns valid value for pri_size");
+       T_EXPECT_EQ_UINT(preginfo.pri_depth, 0U, "PROC_PIDREGIONINFO returns valid value for pri_depth");
+
+       int ret = 0;
+       ret     = munmap(map_tmp, PAGE_SIZE);
+       T_QUIET;
+       T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
+       free_proc_info(proc_info, 1);
+}
+
+T_DECL(proc_info_proc_pidregionpathinfo,
+       "Test to verify PROC_PIDREGIONPATHINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_INSTALLEDUSEROS))
+{
+       void * proc_info[2];
+       void * map_tmp = NULL;
+       proc_info_caller(PREGINFO_PATH, proc_info, NULL);
+
+       struct proc_regionwithpathinfo preginfo_path = *((struct proc_regionwithpathinfo *)proc_info[0]);
+       /*
+        *      map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
+            */
+       map_tmp = proc_info[1];
+
+       T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_offset, (uint64_t)PAGE_SIZE,
+                          "PROC_PIDREGIONPATHINFO returns valid value for pri_offset");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_protection ^ (VM_PROT_READ | VM_PROT_WRITE)), 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_protection, expected read/write only");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_max_protection & (VM_PROT_READ | VM_PROT_WRITE)),
+                        (unsigned int)(VM_PROT_READ | VM_PROT_WRITE),
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_max_protection");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_inheritance");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_behavior");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_wired_count, 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_user_wired_count");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_tag, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_user_tag");
+       T_EXPECT_NE_UINT((preginfo_path.prp_prinfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_flags");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_resident");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_shared_now_private, 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_shared_now_private");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_swapped_out, 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_swapped_out");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_dirtied, 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_dirtied");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_ref_count, 2U, "PROC_PIDREGIONPATHINFO returns valid value for pri_ref_count");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shadow_depth, 1U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_shadow_depth");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_share_mode, (unsigned int)SM_COW,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_share_mode");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_private_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_private_pages_resident");
+       T_EXPECT_GE_UINT(preginfo_path.prp_prinfo.pri_shared_pages_resident, 1U,
+                        "PROC_PIDREGIONPATHINFO returns valid value for pri_shared_pages_resident");
+       T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_address, (uint64_t)map_tmp,
+                          "PROC_PIDREGIONPATHINFO returns valid value for pri_addr");
+       T_EXPECT_NE_UINT(preginfo_path.prp_prinfo.pri_obj_id, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_obj_id");
+       T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_size, (uint64_t)PAGE_SIZE,
+                          "PROC_PIDREGIONPATHINFO returns valid value for pri_size");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_depth, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_depth");
+       T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_type, VREG, "PROC_PIDREGIONPATHINFO returns valid value for vi_type");
+       T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_pad, 0, "PROC_PIDREGIONPATHINFO returns valid value for vi_pad");
+       T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[0], 0,
+                       "PROC_PIDREGIONPATHINFO returns valid value for vi_fsid.val[0]");
+       T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[1], 0,
+                       "PROC_PIDREGIONPATHINFO returns valid value for vi_fsid.val[1]");
+       T_EXPECT_NE_PTR((void *)(strcasestr(preginfo_path.prp_vip.vip_path, CONF_TMP_FILE_PATH)), NULL,
+                       "PROC_PIDREGIONPATHINFO returns valid value for vi_path");
+       /*
+        * Basic sanity checks for vnode stat returned by the API
+        */
+       T_EXPECT_NE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_dev");
+       T_EXPECT_EQ_INT(((preginfo_path.prp_vip.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFREG), 0,
+                       "PROC_PIDREGIONPATHINFO returns valid value for vst_mode");
+       T_EXPECT_EQ_USHORT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_nlink, (unsigned short)1,
+                          "PROC_PIDREGIONPATHINFO returns valid value for vst_nlink");
+       T_EXPECT_NE_ULLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_ino, 0ULL,
+                          "PROC_PIDREGIONPATHINFO returns valid value for vst_ino");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_uid");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_gid");
+       T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_size, (off_t)CONF_BLK_SIZE,
+                         "PROC_PIDREGIONPATHINFO returns valid value for vst_size");
+       T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blocks, 1LL,
+                         "PROC_PIDREGIONPATHINFO returns valid value for vst_blocks");
+       T_EXPECT_GE_INT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
+                       "PROC_PIDREGIONPATHINFO returns valid value for vst_blksize");
+
+       int ret = 0;
+       ret     = munmap(map_tmp, PAGE_SIZE);
+       T_QUIET;
+       T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
+       free_proc_info(proc_info, 1);
+}
+
+T_DECL(proc_info_proc_pidregionpathinfo2,
+       "Test to verify PROC_PIDREGIONPATHINFO2 returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_INSTALLEDUSEROS))
+{
+       void * proc_info[2];
+       void * map_tmp = NULL;
+       proc_info_caller(PREGINFO_PATH_2, proc_info, NULL);
+
+       struct proc_regionwithpathinfo preginfo_path = *((struct proc_regionwithpathinfo *)proc_info[0]);
+       /*
+        *      map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
+            */
+       map_tmp = proc_info[1];
+
+       T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_offset, (uint64_t)PAGE_SIZE,
+                          "PROC_PIDREGIONPATHINFO2 returns valid value for pri_offset");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_protection ^ (VM_PROT_READ | VM_PROT_WRITE)), 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_protection, expected read/write only");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_max_protection & (VM_PROT_READ | VM_PROT_WRITE)),
+                        (unsigned int)(VM_PROT_READ | VM_PROT_WRITE),
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_max_protection");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_inheritance");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_behavior");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_wired_count, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_user_wired_count");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_tag, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_user_tag");
+       T_EXPECT_NE_UINT((preginfo_path.prp_prinfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_flags");
+       /*
+        * Following values are hard-coded to be zero in source
+        */
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_resident");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_shared_now_private, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_shared_now_private");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_swapped_out, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_swapped_out");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_dirtied, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_dirtied");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_ref_count, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_ref_count");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shadow_depth, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_shadow_depth");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_share_mode, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_share_mode");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_private_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_private_pages_resident");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shared_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for pri_shared_pages_resident");
+       T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_address, (uint64_t)map_tmp,
+                          "PROC_PIDREGIONPATHINFO2 returns valid value for pri_addr");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_obj_id, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_obj_id");
+       T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_size, (unsigned long long)PAGE_SIZE,
+                          "PROC_PIDREGIONPATHINFO2 returns valid value for pri_size");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_depth, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_depth");
+
+       T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_type, VREG, "PROC_PIDREGIONPATHINFO2 returns valid value for vi_type");
+       T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_pad, 0, "PROC_PIDREGIONPATHINFO2 returns valid value for vi_pad");
+       T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[0], 0,
+                       "PROC_PIDREGIONPATHINFO2 returns valid value for vi_fsid.val[0]:%d",
+                       preginfo_path.prp_vip.vip_vi.vi_fsid.val[0]);
+       T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[1], 0,
+                       "PROC_PIDREGIONPATHINFO2 returns valid value for vi_fsid.val[1]:%d",
+                       preginfo_path.prp_vip.vip_vi.vi_fsid.val[1]);
+       T_EXPECT_NE_PTR((void *)(strcasestr(preginfo_path.prp_vip.vip_path, CONF_TMP_FILE_PATH)), NULL,
+                       "PROC_PIDREGIONPATHINFO2 returns valid value for vi_path");
+       /*
+        * Basic sanity checks for vnode stat returned by the API
+        */
+       T_EXPECT_NE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_dev");
+       T_EXPECT_EQ_UINT(((preginfo_path.prp_vip.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFREG), 0,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for vst_mode");
+       T_EXPECT_EQ_USHORT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_nlink, (unsigned short)1,
+                          "PROC_PIDREGIONPATHINFO2 returns valid value for vst_nlink");
+       T_EXPECT_NE_ULLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_ino, 0ULL,
+                          "PROC_PIDREGIONPATHINFO2 returns valid value for vst_ino");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_uid");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_gid");
+       T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_size, (off_t)CONF_BLK_SIZE,
+                         "PROC_PIDREGIONPATHINFO2 returns valid value for vst_size");
+       T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blocks, 1LL,
+                         "PROC_PIDREGIONPATHINFO2 returns valid value for vst_blocks");
+       T_EXPECT_GE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
+                        "PROC_PIDREGIONPATHINFO2 returns valid value for vst_blksize");
+
+       int ret = 0;
+       ret     = munmap(map_tmp, PAGE_SIZE);
+       T_QUIET;
+       T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
+       free_proc_info(proc_info, 1);
+}
+
+T_DECL(proc_info_proc_pidregionpathinfo3,
+       "Test to verify PROC_PIDREGIONPATHINFO3 returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_INSTALLEDUSEROS))
+{
+       void * proc_info[1];
+       proc_info_caller(PREGINFO_PATH_3, proc_info, NULL);
+
+       struct proc_regionwithpathinfo preginfo_path = *((struct proc_regionwithpathinfo *)proc_info[0]);
+
+       T_EXPECT_GE_ULLONG(preginfo_path.prp_prinfo.pri_offset, (uint64_t)PAGE_SIZE,
+                          "PROC_PIDREGIONPATHINFO3 returns valid value for pri_offset");
+       T_EXPECT_NE_UINT((preginfo_path.prp_prinfo.pri_protection ^ (VM_PROT_WRITE | VM_PROT_EXECUTE)), 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_protection");
+#if defined(__arm__) || defined(__arm64__)
+       T_EXPECT_GT_UINT(preginfo_path.prp_prinfo.pri_max_protection, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_max_protection");
+#else
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_max_protection ^ VM_PROT_ALL), 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_max_protection");
+#endif
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_inheritance");
+       T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_behavior");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_wired_count, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_user_wired_count");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_tag, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_user_tag");
+       T_EXPECT_NE_UINT((preginfo_path.prp_prinfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_flags");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_resident");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_shared_now_private, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_shared_now_private");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_swapped_out, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_swapped_out");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_dirtied, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_dirtied");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_ref_count, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_ref_count");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shadow_depth, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_shadow_depth");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_share_mode, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_share_mode");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_private_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_private_pages_resident");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shared_pages_resident, 0U,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for pri_shared_pages_resident");
+       T_EXPECT_NE_ULLONG(preginfo_path.prp_prinfo.pri_address, 0ULL, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_addr");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_obj_id, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_obj_id");
+       T_EXPECT_GE_ULLONG(preginfo_path.prp_prinfo.pri_size, (uint64_t)PAGE_SIZE,
+                          "PROC_PIDREGIONPATHINFO3 returns valid value for pri_size");
+       T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_depth, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_depth");
+
+       T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_type, VREG, "PROC_PIDREGIONPATHINFO3 returns valid value for vi_type");
+       T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_pad, 0, "PROC_PIDREGIONPATHINFO3 returns valid value for vi_pad");
+       T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[0], 0,
+                       "PROC_PIDREGIONPATHINFO3 returns valid value for vi_fsid.val[0]");
+       T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[1], 0,
+                       "PROC_PIDREGIONPATHINFO3 returns valid value for vi_fsid.val[1]");
+       /*
+        * Basic sanity checks for vnode stat returned by the API
+        */
+       T_EXPECT_NE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_dev");
+       T_EXPECT_EQ_UINT(((preginfo_path.prp_vip.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFREG), 0,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for vst_mode");
+       T_EXPECT_EQ_USHORT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_nlink, (unsigned short)1,
+                          "PROC_PIDREGIONPATHINFO3 returns valid value for vst_nlink");
+       T_EXPECT_NE_ULLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_ino, 0ULL,
+                          "PROC_PIDREGIONPATHINFO3 returns valid value for vst_ino");
+       /*
+        * No way to confirm actual ownership or binary. Just log the value
+        */
+       T_EXPECT_GE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_uid");
+       T_EXPECT_GE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_gid");
+       T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_size, (off_t)CONF_BLK_SIZE,
+                         "PROC_PIDREGIONPATHINFO3 returns valid value for vst_size");
+       T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blocks, 1LL,
+                         "PROC_PIDREGIONPATHINFO3 returns valid value for vst_blocks");
+       T_EXPECT_GE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
+                        "PROC_PIDREGIONPATHINFO3 returns valid value for vst_blksize");
+
+       free_proc_info(proc_info, 1);
+}
+
+T_DECL(proc_info_proc_pidvnodepathinfo,
+       "Test to verify PROC_PIDVNODEPATHINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       void * proc_info[1];
+       proc_info_caller(PVNINFO, proc_info, NULL);
+       struct proc_vnodepathinfo pvninfo = *((struct proc_vnodepathinfo *)proc_info[0]);
+
+       T_EXPECT_EQ_INT(pvninfo.pvi_cdir.vip_vi.vi_type, VDIR, "PROC_PIDVNODEPATHINFO returns valid value for vi_type");
+       T_EXPECT_EQ_INT(pvninfo.pvi_cdir.vip_vi.vi_pad, 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_pad");
+       T_EXPECT_NE_INT(pvninfo.pvi_cdir.vip_vi.vi_fsid.val[0], 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_fsid.val[0]");
+       T_EXPECT_NE_INT(pvninfo.pvi_cdir.vip_vi.vi_fsid.val[1], 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_fsid.val[1]");
+       /*
+        * Basic sanity checks for vnode stat returned by the API
+        */
+       T_EXPECT_NE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDVNODEPATHINFO returns valid value for vst_dev");
+       T_EXPECT_EQ_INT(((pvninfo.pvi_cdir.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFDIR), 0,
+                       "PROC_PIDVNODEPATHINFO returns valid value for vst_mode");
+       T_EXPECT_GE_USHORT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_nlink, (unsigned short)2,
+                          "PROC_PIDVNODEPATHINFO returns valid value for vst_nlink");
+       T_EXPECT_NE_ULLONG(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_ino, 0ULL, "PROC_PIDVNODEPATHINFO returns valid value for vst_ino");
+       T_EXPECT_GE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_uid");
+       T_EXPECT_GE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_gid");
+       T_EXPECT_GT_LLONG(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_size, 0LL, "PROC_PIDVNODEPATHINFO returns valid value for vst_size");
+       T_EXPECT_GE_LLONG(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_blocks, 0LL, "PROC_PIDVNODEPATHINFO returns valid value for vst_blocks");
+       T_EXPECT_GE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
+                        "PROC_PIDVNODEPATHINFO returns valid value for vst_blksize");
+
+       free_proc_info(proc_info, 1);
+}
+/*
+ * The remaining tests break from the pattern of the other PROC_INFO_CALL_PIDINFO tests.
+ * We call proc_info directly as it's more efficient
+ */
+
+T_DECL(proc_info_pidinfo_proc_pidlistfds,
+       "proc_info API tests to verify PROC_INFO_CALL_PIDINFO/PROC_PIDLISTFDS",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       int retval;
+       int orig_nfiles              = 0;
+       struct proc_fdinfo * fd_info = NULL;
+
+       T_LOG("Test to verify PROC_PIDLISTFDS returns sane number of open files");
+       retval      = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFDS, (uint32_t)0, (user_addr_t)0, (uint32_t)0);
+       orig_nfiles = retval / (int)sizeof(struct proc_fdinfo);
+       T_EXPECT_GE_INT(orig_nfiles, CONF_OPN_FILE_COUNT, "The number of open files is lower than expected.");
+
+       /*
+         * Allocate a buffer of expected size + 1 to ensure that
+         * the API still returns expected size
+         * i.e. 3 + 1 = 4 open fds
+         */
+       T_LOG("Test to verify PROC_PIDLISTFDS returns valid fd information");
+       fd_info = malloc(sizeof(*fd_info) * 5);
+       tmp_fd  = open(CONF_TMP_FILE_PATH, O_RDONLY | O_CREAT);
+       T_LOG("tmp_fd val:%d", tmp_fd);
+       T_QUIET;
+       T_EXPECT_POSIX_SUCCESS(tmp_fd, "open() for PROC_PIDLISTFDS");
+
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFDS, (uint32_t)0, (user_addr_t)fd_info,
+                            (uint32_t)(sizeof(*fd_info) * 5));
+       retval = retval / (int)sizeof(struct proc_fdinfo);
+
+       close(tmp_fd);
+
+       for (int i = 0; i < retval; i++) {
+               /*
+                * Check only for the fd that we control.
+                */
+               if (tmp_fd != fd_info[i].proc_fd) {
+                       continue;
+               }
+               T_EXPECT_EQ_UINT(fd_info[i].proc_fdtype, (unsigned int)PROX_FDTYPE_VNODE, "Correct proc_fdtype for returned fd");
+       }
+
+       T_EXPECT_GE_INT(retval, 4, "Correct number of fds was returned.");
+
+       tmp_fd = -1;
+       free(fd_info);
+       fd_info = NULL;
+}
+
+T_DECL(proc_info_proc_pidpathinfo,
+       "Test to verify PROC_PIDPATHINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       char * pid_path = NULL;
+       pid_path        = malloc(sizeof(char) * PROC_PIDPATHINFO_MAXSIZE);
+       T_EXPECT_NOTNULL(pid_path, "malloc for PROC_PIDPATHINFO");
+       int retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDPATHINFO, (uint64_t)0, (user_addr_t)pid_path,
+                                (uint32_t)PROC_PIDPATHINFO_MAXSIZE);
+       T_EXPECT_EQ_INT(retval, 0, "__proc_info call for PROC_PIDPATHINFO");
+
+       T_EXPECT_NE_PTR((void *)(strcasestr(pid_path, CONF_CMD_NAME)), NULL, "PROC_PIDPATHINFOreturns valid value for pid_path");
+       free(pid_path);
+       pid_path = NULL;
+}
+
+T_DECL(proc_info_proc_pidlistfileports,
+       "Test to verify PROC_PIDLISTFILEPORTS returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       struct proc_fileportinfo * fileport_info = NULL;
+       mach_port_t tmp_file_port                = MACH_PORT_NULL;
+       proc_config_t proc_config                = spawn_child_processes(1, proc_info_call_pidinfo_handler);
+       int child_pid                            = proc_config->child_pids[0];
+
+       /*
+        * Create a file port
+        */
+       tmp_fd     = open(CONF_TMP_FILE_PATH, O_RDWR | O_CREAT);
+       int retval = fileport_makeport(tmp_fd, &tmp_file_port);
+       T_EXPECT_POSIX_SUCCESS(retval, "fileport_makeport() for PROC_PIDLISTFILEPORTS");
+
+       /*
+        * Like the other APIs, this returns the actual count + 20. Hence we expect it to be atleast 1 (that we created)
+        */
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFILEPORTS, (uint64_t)0, (user_addr_t)0, (uint32_t)0);
+       T_EXPECT_GE_INT(retval / (int)sizeof(fileport_info), 1,
+                       "__proc_info call for PROC_PIDLISTFILEPORTS to get total ports in parent");
+
+       /*
+        * Child doesn't have any fileports, should return zero
+        */
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDLISTFILEPORTS, (uint64_t)0, (user_addr_t)0, (uint32_t)0);
+       T_EXPECT_EQ_INT(retval / (int)sizeof(fileport_info), 0,
+                       "__proc_info call for PROC_PIDLISTFILEPORTS to get total ports in child");
+
+       fileport_info = malloc(sizeof(*fileport_info) * (size_t)retval);
+       retval        = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFILEPORTS, (uint64_t)0, (user_addr_t)fileport_info,
+                            (uint32_t)sizeof(*fileport_info));
+       T_EXPECT_EQ_INT(retval, (int)sizeof(*fileport_info), "__proc_info call for PROC_PIDLISTFILEPORTS");
+
+       T_EXPECT_NE_UINT(fileport_info->proc_fileport, (uint32_t)0, "PROC_PIDLISTFILEPORTS returns valid value for proc_fileport");
+       T_EXPECT_EQ_UINT(fileport_info->proc_fdtype, (uint32_t)PROX_FDTYPE_VNODE,
+                        "PROC_PIDLISTFILEPORTS returns valid value for proc_fdtype");
+
+       /*
+        * Cleanup for the fileport
+        */
+       mach_port_deallocate(mach_task_self(), tmp_file_port);
+       tmp_file_port = MACH_PORT_NULL;
+       free(fileport_info);
+       fileport_info = NULL;
+       close(tmp_fd);
+       tmp_fd = -1;
+       free_proc_config(proc_config);
+}
+
+T_DECL(proc_info_proc_pidcoalitioninfo,
+       "Test to verify PROC_PIDCOALITIONINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
+       int child_pid             = proc_config->child_pids[0];
+
+       struct proc_pidcoalitioninfo pci_parent;
+       struct proc_pidcoalitioninfo pci_child;
+       int retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDCOALITIONINFO, (uint64_t)0, (user_addr_t)&pci_parent,
+                                (uint32_t)sizeof(pci_parent));
+       T_EXPECT_EQ_INT(retval, (int)sizeof(pci_parent), "__proc_info call for PROC_PIDCOALITIONINFO (parent)");
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDCOALITIONINFO, (uint64_t)0, (user_addr_t)&pci_child,
+                            (uint32_t)sizeof(pci_child));
+       T_EXPECT_EQ_INT(retval, (int)sizeof(pci_child), "__proc_info call for PROC_PIDCOALITIONINFO (child)");
+
+       /*
+        * Coalition IDs should match for child and parent
+        */
+       for (int i = 0; i < COALITION_NUM_TYPES; i++) {
+               T_EXPECT_EQ_ULLONG(pci_parent.coalition_id[i], pci_child.coalition_id[i],
+                                  "PROC_PIDCOALITIONINFO returns valid value for coalition_id");
+       }
+
+       free_proc_config(proc_config);
+}
+
+T_DECL(proc_info_proc_pidworkqueueinfo,
+       "Test to verify PROC_PIDWORKQUEUEINFO returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
+       int child_pid             = proc_config->child_pids[0];
+       send_action_to_child_processes(proc_config, ACT_PHASE5);
+
+       struct proc_workqueueinfo pwqinfo;
+       usleep(10000);
+       int retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDWORKQUEUEINFO, (uint64_t)0, (user_addr_t)&pwqinfo,
+                                (uint32_t)sizeof(pwqinfo));
+       T_EXPECT_EQ_INT(retval, (int)sizeof(pwqinfo), "__proc_info call for PROC_PIDWORKQUEUEINFO");
+
+       int ncpu         = 0;
+       size_t ncpu_size = sizeof(ncpu);
+       retval           = sysctlbyname("hw.ncpu", (void *)&ncpu, &ncpu_size, NULL, 0);
+       T_EXPECT_EQ_INT(retval, 0, "sysctl() for PROC_PIDWORKQUEUEINFO");
+       T_EXPECT_GE_UINT(pwqinfo.pwq_nthreads, (uint32_t)1, "PROC_PIDWORKQUEUEINFO returns valid value for pwq_nthreads");
+       T_EXPECT_GE_UINT(pwqinfo.pwq_blockedthreads + pwqinfo.pwq_runthreads, (uint32_t)1,
+                        "PROC_PIDWORKQUEUEINFO returns valid value for pwqinfo.pwq_runthreads/pwq_blockedthreads");
+       T_EXPECT_EQ_UINT(pwqinfo.pwq_state, (uint32_t)0, "PROC_PIDWORKQUEUEINFO returns valid value for pwq_state");
+
+       kill_child_processes(proc_config);
+       free_proc_config(proc_config);
+}
+T_DECL(proc_info_proc_pidnoteexit,
+       "Test to verify PROC_PIDNOTEEXIT returns valid information about the process",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       /*
+        * Ask the child to close pipe and quit, cleanup pipes for parent
+        */
+       proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
+       int child_pid             = proc_config->child_pids[0];
+       send_action_to_child_processes(proc_config, ACT_EXIT);
+
+       uint32_t exit_data = 0;
+       int retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDNOTEEXIT, (uint64_t)(NOTE_EXITSTATUS | NOTE_EXIT_DETAIL),
+                                (user_addr_t)&exit_data, (uint32_t)sizeof(exit_data));
+       T_EXPECT_EQ_INT(retval, (int)sizeof(exit_data), "__proc_info call for PROC_PIDNOTEEXIT");
+
+       T_EXPECT_EQ_UINT(exit_data, 0U, "PROC_PIDNOTEEXIT returned valid value for exit_data");
+
+       free_proc_config(proc_config);
+}
+
+T_DECL(proc_info_negative_tests,
+       "Test to validate PROC_INFO_CALL_PIDINFO for invalid arguments",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
+       int child_pid             = proc_config->child_pids[0];
+       uint32_t exit_data        = 0;
+
+       int retval =
+           __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDNOTEEXIT, (uint64_t)0, (user_addr_t)&exit_data, (uint32_t)0);
+       T_EXPECT_EQ_INT(errno, ENOMEM, "PROC_INFO_CALL_PIDINFO call should fail with ENOMEM if buffersize is zero");
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDPATHINFO, (uint64_t)0, (user_addr_t)&exit_data,
+                            (uint32_t)PROC_PIDPATHINFO_MAXSIZE + 1);
+       T_EXPECT_EQ_INT(errno, EOVERFLOW,
+                       "PROC_INFO_CALL_PIDINFO call should fail with EOVERFLOW if buffersize is larger than PROC_PIDPATHINFO_MAXSIZE");
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, -1, PROC_PIDNOTEEXIT, (uint64_t)0, (user_addr_t)&exit_data,
+                            (uint32_t)sizeof(exit_data));
+       T_EXPECT_EQ_INT(errno, ESRCH, "PROC_INFO_CALL_PIDINFO call should fail with ESRCH for invalid process id");
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, -1U, (uint64_t)0, (user_addr_t)&exit_data, (uint32_t)sizeof(exit_data));
+       T_EXPECT_EQ_INT(errno, EINVAL, "PROC_INFO_CALL_PIDINFO call should fail with EINVAL for invalid flavor");
+       retval = __proc_info(PROC_INFO_CALL_PIDINFO, 0, PROC_PIDWORKQUEUEINFO, (uint64_t)0, (user_addr_t)0, (uint32_t)0);
+       T_EXPECT_EQ_INT(errno, EINVAL,
+                       "PROC_INFO_CALL_PIDINFO call should fail with EINVAL if flavor is PROC_PIDWORKQUEUEINFO and pid=0");
+
+       free_proc_config(proc_config);
+}
+
+/*
+ * END PROC_INFO_CALL_PIDINFO DECLs
+ */
 
 #pragma mark proc_list_uptrs
 
 #define NUPTRS 4
-static uint64_t uptrs[NUPTRS] = {
-       0x1122334455667788ULL,
-       0x99aabbccddeeff00ULL,
-       0xaabbaaddccaaffeeULL,
-       0xcc000011ccaa7755ULL
-};
+static uint64_t uptrs[NUPTRS] = {0x1122334455667788ULL, 0x99aabbccddeeff00ULL, 0xaabbaaddccaaffeeULL, 0xcc000011ccaa7755ULL};
 
-static const char *uptr_names[NUPTRS];
+static const char * uptr_names[NUPTRS];
 
 static void
-print_uptrs(int argc, char * const *argv)
+print_uptrs(int argc, char * const * argv)
 {
        for (int i = 0; i < argc; i++) {
-               char *end;
+               char * end;
                unsigned long pid = strtoul(argv[i], &end, 0);
                if (pid > INT_MAX) {
                        printf("error: pid '%lu' would overflow an integer\n", pid);
@@ -52,11 +1843,10 @@ print_uptrs(int argc, char * const *argv)
                /* extra space */
                unsigned int uptrs_len = (unsigned int)uptrs_count + 32;
 
-               uint64_t *uptrs_alloc = malloc(sizeof(uint64_t) * uptrs_len);
+               uint64_t * uptrs_alloc = malloc(sizeof(uint64_t) * uptrs_len);
                os_assert(uptrs_alloc != NULL);
 
-               uptrs_count = proc_list_uptrs((int)pid, uptrs_alloc,
-                               (uint32_t)(sizeof(uint64_t) * uptrs_len));
+               uptrs_count = proc_list_uptrs((int)pid, uptrs_alloc, (uint32_t)(sizeof(uint64_t) * uptrs_len));
                printf("process %d has %d uptrs:\n", (int)pid, uptrs_count);
                if (uptrs_count > (int)uptrs_len) {
                        uptrs_count = (int)uptrs_len;
@@ -67,9 +1857,7 @@ print_uptrs(int argc, char * const *argv)
        }
 }
 
-T_DECL(proc_list_uptrs,
-       "the kernel should return any up-pointers it knows about",
-       T_META_ALL_VALID_ARCHS(YES))
+T_DECL(proc_list_uptrs, "the kernel should return any up-pointers it knows about", T_META_ALL_VALID_ARCHS(YES))
 {
        if (argc > 0) {
                print_uptrs(argc, argv);
@@ -79,7 +1867,8 @@ T_DECL(proc_list_uptrs,
        unsigned int cur_uptr = 0;
 
        int kq = kqueue();
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(kq, "kqueue");
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(kq, "kqueue");
 
        /*
         * Should find uptrs on file-type knotes and generic knotes (two
@@ -89,47 +1878,42 @@ T_DECL(proc_list_uptrs,
        memset(events, 0, sizeof(events));
 
        uptr_names[cur_uptr] = "kqueue file-backed knote";
-       events[0].filter = EVFILT_WRITE;
-       events[0].ident = STDOUT_FILENO;
-       events[0].flags = EV_ADD;
-       events[0].udata = uptrs[cur_uptr++];
+       events[0].filter     = EVFILT_WRITE;
+       events[0].ident      = STDOUT_FILENO;
+       events[0].flags      = EV_ADD;
+       events[0].udata      = uptrs[cur_uptr++];
 
        uptr_names[cur_uptr] = "kqueue non-file-backed knote";
-       events[1].filter = EVFILT_USER;
-       events[1].ident = 1;
-       events[1].flags = EV_ADD;
-       events[1].udata = uptrs[cur_uptr++];
+       events[1].filter     = EVFILT_USER;
+       events[1].ident      = 1;
+       events[1].flags      = EV_ADD;
+       events[1].udata      = uptrs[cur_uptr++];
 
-       int kev_err = kevent64(kq, events, sizeof(events) / sizeof(events[0]), NULL,
-                       0, KEVENT_FLAG_IMMEDIATE, NULL);
+       int kev_err = kevent64(kq, events, sizeof(events) / sizeof(events[0]), NULL, 0, KEVENT_FLAG_IMMEDIATE, NULL);
        T_ASSERT_POSIX_SUCCESS(kev_err, "register events with kevent64");
 
        /*
         * Should find uptrs both on a kevent_id kqueue and in a workloop
         * kqueue's knote's udata field.
         */
-       uptr_names[cur_uptr] = "dynamic kqueue non-file-backed knote";
-       struct kevent_qos_s events_id[] = {{
-               .filter = EVFILT_USER,
-               .ident = 1,
-               .flags = EV_ADD,
-               .udata = uptrs[cur_uptr++]
-       }};
+       uptr_names[cur_uptr]            = "dynamic kqueue non-file-backed knote";
+       struct kevent_qos_s events_id[] = {{.filter = EVFILT_USER, .ident = 1, .flags = EV_ADD, .udata = uptrs[cur_uptr++]}};
 
        uptr_names[cur_uptr] = "dynamic kqueue ID";
-       kev_err = kevent_id(uptrs[cur_uptr++], events_id, 1, NULL, 0, NULL, NULL,
-                       KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_IMMEDIATE);
+       kev_err = kevent_id(uptrs[cur_uptr++], events_id, 1, NULL, 0, NULL, NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_IMMEDIATE);
        T_ASSERT_POSIX_SUCCESS(kev_err, "register event with kevent_id");
 
-       errno = 0;
+       errno           = 0;
        int uptrs_count = proc_list_uptrs(getpid(), NULL, 0);
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(uptrs_count, "proc_list_uptrs");
-       T_QUIET; T_EXPECT_EQ(uptrs_count, NUPTRS,
-                       "should see correct number of up-pointers");
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(uptrs_count, "proc_list_uptrs");
+       T_QUIET;
+       T_EXPECT_EQ(uptrs_count, NUPTRS, "should see correct number of up-pointers");
 
-       uint64_t uptrs_obs[NUPTRS] = { 0 };
-       uptrs_count = proc_list_uptrs(getpid(), uptrs_obs, sizeof(uptrs_obs));
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(uptrs_count, "proc_list_uptrs");
+       uint64_t uptrs_obs[NUPTRS] = {0};
+       uptrs_count                = proc_list_uptrs(getpid(), uptrs_obs, sizeof(uptrs_obs));
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(uptrs_count, "proc_list_uptrs");
 
        for (int i = 0; i < uptrs_count; i++) {
                int found = -1;
@@ -140,7 +1924,7 @@ T_DECL(proc_list_uptrs,
                        }
                }
                T_FAIL("unexpected up-pointer found: %#" PRIx64, uptrs_obs[i]);
-next:;
+       next:;
                if (found != -1) {
                        T_PASS("found up-pointer for %s", uptr_names[found]);
                }
@@ -153,7 +1937,7 @@ next:;
 
 #pragma mark dynamic kqueue info
 
-#define EXPECTED_ID    UINT64_C(0x1122334455667788)
+#define EXPECTED_ID UINT64_C(0x1122334455667788)
 #define EXPECTED_UDATA UINT64_C(0x99aabbccddeeff00)
 #ifndef KQ_WORKLOOP
 #define KQ_WORKLOOP 0x80
@@ -162,35 +1946,31 @@ next:;
 static void
 setup_kevent_id(kqueue_id_t id)
 {
-       struct kevent_qos_s events_id[] = {{
-               .filter = EVFILT_USER,
-               .ident = 1,
-               .flags = EV_ADD,
-               .udata = EXPECTED_UDATA
-       }};
+       struct kevent_qos_s events_id[] = {{.filter = EVFILT_USER, .ident = 1, .flags = EV_ADD, .udata = EXPECTED_UDATA}};
 
-       int err = kevent_id(id, events_id, 1, NULL, 0, NULL, NULL,
-                       KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_IMMEDIATE);
+       int err = kevent_id(id, events_id, 1, NULL, 0, NULL, NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_IMMEDIATE);
        T_ASSERT_POSIX_SUCCESS(err, "register event with kevent_id");
 }
 
 static kqueue_id_t *
-list_kqids(pid_t pid, int *nkqids_out)
+list_kqids(pid_t pid, int * nkqids_out)
 {
        int kqids_len = 256;
        int nkqids;
-       kqueue_id_t *kqids = NULL;
+       kqueue_id_t * kqids = NULL;
        uint32_t kqids_size;
 
 retry:
        if (os_mul_overflow(sizeof(kqueue_id_t), kqids_len, &kqids_size)) {
-               T_QUIET; T_ASSERT_GT(kqids_len, PROC_PIDDYNKQUEUES_MAX, NULL);
+               T_QUIET;
+               T_ASSERT_GT(kqids_len, PROC_PIDDYNKQUEUES_MAX, NULL);
                kqids_len = PROC_PIDDYNKQUEUES_MAX;
                goto retry;
        }
        if (!kqids) {
                kqids = malloc(kqids_size);
-               T_QUIET; T_ASSERT_NOTNULL(kqids, "malloc(%" PRIu32 ")", kqids_size);
+               T_QUIET;
+               T_ASSERT_NOTNULL(kqids, "malloc(%" PRIu32 ")", kqids_size);
        }
 
        nkqids = proc_list_dynkqueueids(pid, kqids, kqids_size);
@@ -208,15 +1988,13 @@ retry:
        return kqids;
 }
 
-T_DECL(list_dynamic_kqueues,
-               "the kernel should list IDs of dynamic kqueues",
-               T_META_ALL_VALID_ARCHS(true))
+T_DECL(list_dynamic_kqueues, "the kernel should list IDs of dynamic kqueues", T_META_ALL_VALID_ARCHS(true))
 {
        int nkqids;
        bool found = false;
 
        setup_kevent_id(EXPECTED_ID);
-       kqueue_id_t *kqids = list_kqids(getpid(), &nkqids);
+       kqueue_id_t * kqids = list_kqids(getpid(), &nkqids);
        T_ASSERT_GE(nkqids, 1, "at least one dynamic kqueue is listed");
        for (int i = 0; i < nkqids; i++) {
                if (kqids[i] == EXPECTED_ID) {
@@ -234,93 +2012,81 @@ T_DECL(list_dynamic_kqueues,
        free(kqids);
 }
 
-T_DECL(dynamic_kqueue_basic_info,
-               "the kernel should report valid basic dynamic kqueue info",
-               T_META_ALL_VALID_ARCHS(true))
+T_DECL(dynamic_kqueue_basic_info, "the kernel should report valid basic dynamic kqueue info", T_META_ALL_VALID_ARCHS(true))
 {
        struct kqueue_info kqinfo;
        int ret;
 
        setup_kevent_id(EXPECTED_ID);
-       ret = proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_INFO, EXPECTED_ID,
-                       &kqinfo, sizeof(kqinfo));
-       T_ASSERT_POSIX_SUCCESS(ret,
-                       "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_INFO ...)");
-       T_QUIET; T_ASSERT_GE(ret, (int)sizeof(kqinfo),
-                       "PROC_PIDDYNKQUEUE_INFO should return the right size");
+       ret = proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_INFO, EXPECTED_ID, &kqinfo, sizeof(kqinfo));
+       T_ASSERT_POSIX_SUCCESS(ret, "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_INFO ...)");
+       T_QUIET;
+       T_ASSERT_GE(ret, (int)sizeof(kqinfo), "PROC_PIDDYNKQUEUE_INFO should return the right size");
 
-       T_EXPECT_NE(kqinfo.kq_state & KQ_WORKLOOP, 0U,
-                       "kqueue info should be for a workloop kqueue");
-       T_EXPECT_EQ(kqinfo.kq_stat.vst_ino, EXPECTED_ID,
-                       "inode field should be the kqueue's ID");
+       T_EXPECT_NE(kqinfo.kq_state & KQ_WORKLOOP, 0U, "kqueue info should be for a workloop kqueue");
+       T_EXPECT_EQ(kqinfo.kq_stat.vst_ino, EXPECTED_ID, "inode field should be the kqueue's ID");
 }
 
-T_DECL(dynamic_kqueue_extended_info,
-               "the kernel should report valid extended dynamic kqueue info",
-               T_META_ALL_VALID_ARCHS(true))
+T_DECL(dynamic_kqueue_extended_info, "the kernel should report valid extended dynamic kqueue info", T_META_ALL_VALID_ARCHS(true))
 {
        struct kevent_extinfo kqextinfo[1];
        int ret;
 
        setup_kevent_id(EXPECTED_ID);
-       ret = proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_EXTINFO,
-                       EXPECTED_ID, kqextinfo, sizeof(kqextinfo));
-       T_ASSERT_POSIX_SUCCESS(ret,
-                       "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_EXTINFO ...)");
-       T_QUIET; T_ASSERT_EQ(ret, 1,
-                       "PROC_PIDDYNKQUEUE_EXTINFO should return a single knote");
+       ret = proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_EXTINFO, EXPECTED_ID, kqextinfo, sizeof(kqextinfo));
+       T_ASSERT_POSIX_SUCCESS(ret, "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_EXTINFO ...)");
+       T_QUIET;
+       T_ASSERT_EQ(ret, 1, "PROC_PIDDYNKQUEUE_EXTINFO should return a single knote");
 
-       T_EXPECT_EQ(kqextinfo[0].kqext_kev.ident, 1ULL,
-                       "kevent identifier matches what was configured");
-       T_EXPECT_EQ(kqextinfo[0].kqext_kev.filter, (short)EVFILT_USER,
-                       "kevent filter matches what was configured");
-       T_EXPECT_EQ(kqextinfo[0].kqext_kev.udata, EXPECTED_UDATA,
-                       "kevent udata matches what was configured");
+       T_EXPECT_EQ(kqextinfo[0].kqext_kev.ident, 1ULL, "kevent identifier matches what was configured");
+       T_EXPECT_EQ(kqextinfo[0].kqext_kev.filter, (short)EVFILT_USER, "kevent filter matches what was configured");
+       T_EXPECT_EQ(kqextinfo[0].kqext_kev.udata, EXPECTED_UDATA, "kevent udata matches what was configured");
 }
 
 #pragma mark proc_listpids
 
-T_DECL(list_kdebug_pids,
-               "the kernel should report processes that are filtered by kdebug",
-               T_META_ASROOT(YES))
+T_DECL(list_kdebug_pids, "the kernel should report processes that are filtered by kdebug", T_META_ASROOT(YES))
 {
-       int mib[4] = { CTL_KERN, KERN_KDEBUG };
+       int mib[4] = {CTL_KERN, KERN_KDEBUG};
        int npids;
        int pids[1];
        int ret;
-       kd_regtype reg = {};
+       kd_regtype reg;
        size_t regsize = sizeof(reg);
 
        mib[2] = KERN_KDREMOVE;
-       ret = sysctl(mib, 3, NULL, NULL, NULL, 0);
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDREMOVE sysctl");
+       ret    = sysctl(mib, 3, NULL, NULL, NULL, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDREMOVE sysctl");
 
-       mib[2] = KERN_KDSETBUF; mib[3] = 100000;
-       ret = sysctl(mib, 4, NULL, NULL, NULL, 0);
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDSETBUF sysctl");
+       mib[2] = KERN_KDSETBUF;
+       mib[3] = 100000;
+       ret    = sysctl(mib, 4, NULL, NULL, NULL, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDSETBUF sysctl");
 
        mib[2] = KERN_KDSETUP;
-       ret = sysctl(mib, 3, NULL, NULL, NULL, 0);
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDSETUP sysctl");
+       ret    = sysctl(mib, 3, NULL, NULL, NULL, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDSETUP sysctl");
 
        npids = proc_listpids(PROC_KDBG_ONLY, 0, pids, sizeof(pids));
        T_EXPECT_EQ(npids, 0, "no processes should be filtered initially");
 
-       reg.type = KDBG_TYPENONE;
-       reg.value1 = getpid();
+       reg.type   = KDBG_TYPENONE;
+       reg.value1 = (unsigned int)getpid();
        reg.value2 = 1; /* set the pid in the filter */
-       mib[2] = KERN_KDPIDTR;
-       ret = sysctl(mib, 3, &reg, &regsize, NULL, 0);
-       T_ASSERT_POSIX_SUCCESS(ret,
-                       "KERN_KDPIDTR sysctl to set a pid in the filter");
+       mib[2]     = KERN_KDPIDTR;
+       ret        = sysctl(mib, 3, &reg, &regsize, NULL, 0);
+       T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDPIDTR sysctl to set a pid in the filter");
 
        npids = proc_listpids(PROC_KDBG_ONLY, 0, pids, sizeof(pids));
        npids /= 4;
        T_EXPECT_EQ(npids, 1, "a process should be filtered");
-       T_EXPECT_EQ(pids[0], getpid(),
-                       "process filtered should be the one that was set");
+       T_EXPECT_EQ(pids[0], getpid(), "process filtered should be the one that was set");
 
        mib[2] = KERN_KDREMOVE;
-       ret = sysctl(mib, 3, NULL, NULL, NULL, 0);
-       T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDREMOVE sysctl");
+       ret    = sysctl(mib, 3, NULL, NULL, NULL, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDREMOVE sysctl");
 }
diff --git a/tools/tests/darwintests/proc_info_udata.c b/tools/tests/darwintests/proc_info_udata.c
new file mode 100644 (file)
index 0000000..f814be4
--- /dev/null
@@ -0,0 +1,47 @@
+#include <darwintest.h>
+#include "../../../bsd/sys/proc_info.h"
+#include "../../../libsyscall/wrappers/libproc/libproc.h"
+#include <stdio.h>
+#include <unistd.h>
+
+T_DECL(proc_udata_info, "Get and set a proc udata token"){
+       uint64_t token = mach_absolute_time();
+       proc_info_udata_t udata;
+       int ret;
+       
+       udata = token;
+       ret = proc_udata_info(getpid(), PROC_UDATA_INFO_SET, &udata, sizeof (udata));
+
+#if CONFIG_EMBEDDED
+       T_WITH_ERRNO;
+       T_ASSERT_EQ_INT(ret, -1, "proc_udata_info PROC_UDATA_INFO_SET returns error on non-macOS");
+       T_SKIP("Remaining tests are only supported on macOS");
+#endif /* CONFIG_EMBEDDED */
+
+       T_WITH_ERRNO;
+       T_ASSERT_EQ_INT(ret, 0, "proc_udata_info PROC_UDATA_INFO_SET");
+
+       T_LOG("udata set to %#llx", udata);
+
+       bzero(&udata, sizeof (udata));
+       ret = proc_udata_info(getpid(), PROC_UDATA_INFO_GET, &udata, sizeof (udata));
+       T_WITH_ERRNO;
+       T_ASSERT_EQ_INT(ret, 0, "proc_udata_info PROC_UDATA_INFO_GET");
+
+       T_ASSERT_EQ_ULLONG(token, udata, "proc_udata_info(): retrieved value matches token");
+
+       ret = proc_udata_info(getpid(), PROC_UDATA_INFO_SET, &udata, sizeof (uint32_t));
+       T_WITH_ERRNO;
+       T_ASSERT_EQ_INT(ret, -1, "proc_udata_info PROC_UDATA_INFO_SET with invalid size returned -1");
+       T_ASSERT_EQ_INT(errno, EINVAL, "proc_udata_info PROC_UDATA_INFO_SET with invalid size returned EINVAL");
+
+       ret = proc_udata_info(getppid(), PROC_UDATA_INFO_GET, &udata, sizeof (udata));
+       T_WITH_ERRNO;
+       T_ASSERT_EQ_INT(ret, -1, "proc_udata_info PROC_UDATA_INFO_GET returned -1 on attempt against non-self pid");
+       T_ASSERT_EQ_INT(errno, EACCES, "proc_udata_info PROC_UDATA_INFO_GET set errno to EACCES on attempt against non-self pid");
+
+       ret = proc_udata_info(getppid(), PROC_UDATA_INFO_SET, &udata, sizeof (udata));
+       T_WITH_ERRNO;
+       T_ASSERT_EQ_INT(ret, -1, "proc_udata_info PROC_UDATA_INFO_SET returned -1 on attempt against non-self pid");
+       T_ASSERT_EQ_INT(errno, EACCES, "proc_udata_info PROC_UDATA_INFO_SET set errno to EACCES on attempt against non-self pid");
+}
index ae6d68b8826c47f0837aa86f5e601d7744a853cf..6bb495ddb0e8ac180642633c069030191af01b8a 100644 (file)
@@ -15,8 +15,6 @@
 #include <uuid/uuid.h>
 #endif
 
-#define EXIT_FAIL() exit((__LINE__ % 255) + 1)
-
 /*
  * This test expects the entitlement or root privileges for a process to
  * set the time using settimeofday syscall.
 
 #define DAY 86400 //1 day in sec
 
-/*
- * To run without root privileges
- * <rdar://problem/28315048> libdarwintest should run leaks even without root
- */
-static void drop_priv(void){
-       /* determine the less-privileged UID and GID */
-
-       unsigned long lower_uid = 0;
-       unsigned long lower_gid = 0;
-
-#if CONFIG_EMBEDDED
-       struct passwd *pw = getpwnam("mobile");
-       if (!pw) {
-               printf("child: error: get_pwname(\"mobile\") failed %d: %s\n", errno, strerror(errno));
-               EXIT_FAIL();
-       }
-
-       lower_uid = pw->pw_uid;
-       lower_gid = pw->pw_gid;
-#else
-       char *sudo_gid_str = getenv("SUDO_GID");
-       if (!sudo_gid_str) {
-               printf("child: error: SUDO_GID environment variable unset (not run under sudo)\n");
-               EXIT_FAIL();
-       }
-
-       char *sudo_uid_str = getenv("SUDO_UID");
-       if (!sudo_uid_str) {
-               printf("child: error: SUDO_UID environment variable unset (not run under sudo)\n");
-               EXIT_FAIL();
-       }
-
-       char *end = sudo_gid_str;
-       lower_gid = strtoul(sudo_gid_str, &end, 10);
-       if (sudo_gid_str == end && sudo_gid_str[0] != '\0') {
-               printf("child: error: SUDO_GID (%s) could not be converted to an integer\n", sudo_gid_str);
-               EXIT_FAIL();
-       }
-       if (lower_gid == 0) {
-               printf("child: error: less-privileged GID invalid\n");
-               EXIT_FAIL();
-       }
-
-       end = sudo_uid_str;
-       lower_uid = strtoul(sudo_uid_str, &end, 10);
-       if (sudo_uid_str == end && sudo_uid_str[0] != '\0') {
-               printf("child: error: SUDO_UID (%s) could not be converted to an integer\n", sudo_uid_str);
-               EXIT_FAIL();
-       }
-       if (lower_gid == 0) {
-               printf("child: error: less-privileged UID invalid\n");
-               EXIT_FAIL();
-       }
-#endif
-
-       if (setgid(lower_gid) == -1) {
-               printf("child: error: could not change group to %lu\n", lower_gid);
-               EXIT_FAIL();
-       }
-       if (setuid(lower_uid) == -1) {
-               printf("child: error: could not change user to %lu\n", lower_uid);
-               EXIT_FAIL();
-       }
-}
-
 T_DECL(settime_32089962_not_entitled_root,
        "Verify that root privileges can allow to change the time",
-       T_META_ASROOT(true), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(true), T_META_CHECK_LEAKS(false))
 {
        struct timeval settimeofdaytime;
        struct timeval adj_time;
@@ -120,15 +53,13 @@ T_DECL(settime_32089962_not_entitled_root,
 
 T_DECL(settime_32089962_not_entitled_not_root,
        "Verify that the \"com.apple.settime\" entitlement can allow to change the time",
-       T_META_ASROOT(false), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(false), T_META_CHECK_LEAKS(false))
 {
        struct timeval settimeofdaytime;
        struct timeval adj_time;
        struct timex ntptime;
        int res;
 
-       drop_priv();
-
        if (geteuid() == 0){
                 T_SKIP("settimeofday_29193041 test requires no root privileges to run.");
         }
@@ -159,7 +90,7 @@ T_DECL(settime_32089962_not_entitled_not_root,
 
 T_DECL(settimeofday_29193041_not_entitled_root,
        "Verify that root privileges can allow to change the time",
-       T_META_ASROOT(true), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(true), T_META_CHECK_LEAKS(false))
 {
        struct timeval time;
        long new_time;
@@ -189,13 +120,11 @@ T_DECL(settimeofday_29193041_not_entitled_root,
 
 T_DECL(settimeofday_29193041_not_entitled_not_root,
        "Verify that the \"com.apple.settime\" entitlement can allow to change the time",
-       T_META_ASROOT(false), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(false), T_META_CHECK_LEAKS(false))
 {
        struct timeval time;
        long new_time;
 
-       drop_priv();
-
        if (geteuid() == 0){
                 T_SKIP("settimeofday_29193041 test requires no root privileges to run.");
         }
index a68c6cac880365bd03d85a092a7357a5e282762b..51ca5a5ed77a0a93d08a3814607f32f8bc81a7b6 100644 (file)
@@ -15,8 +15,6 @@
 #include <uuid/uuid.h>
 #endif
 
-#define EXIT_FAIL() exit((__LINE__ % 255) + 1)
-
 /*
  * This test expects the entitlement or root privileges for a process to
  * set the time using settimeofday syscall.
 
 #define DAY 86400 //1 day in sec
 
-/*
- * To run without root privileges
- * <rdar://problem/28315048> libdarwintest should run leaks even without root
- */
-static void drop_priv(void){
-       /* determine the less-privileged UID and GID */
-
-       unsigned long lower_uid = 0;
-       unsigned long lower_gid = 0;
-
-#if CONFIG_EMBEDDED
-       struct passwd *pw = getpwnam("mobile");
-       if (!pw) {
-               printf("child: error: get_pwname(\"mobile\") failed %d: %s\n", errno, strerror(errno));
-               EXIT_FAIL();
-       }
-
-       lower_uid = pw->pw_uid;
-       lower_gid = pw->pw_gid;
-#else
-       char *sudo_gid_str = getenv("SUDO_GID");
-       if (!sudo_gid_str) {
-               printf("child: error: SUDO_GID environment variable unset (not run under sudo)\n");
-               EXIT_FAIL();
-       }
-
-       char *sudo_uid_str = getenv("SUDO_UID");
-       if (!sudo_uid_str) {
-               printf("child: error: SUDO_UID environment variable unset (not run under sudo)\n");
-               EXIT_FAIL();
-       }
-
-       char *end = sudo_gid_str;
-       lower_gid = strtoul(sudo_gid_str, &end, 10);
-       if (sudo_gid_str == end && sudo_gid_str[0] != '\0') {
-               printf("child: error: SUDO_GID (%s) could not be converted to an integer\n", sudo_gid_str);
-               EXIT_FAIL();
-       }
-       if (lower_gid == 0) {
-               printf("child: error: less-privileged GID invalid\n");
-               EXIT_FAIL();
-       }
-
-       end = sudo_uid_str;
-       lower_uid = strtoul(sudo_uid_str, &end, 10);
-       if (sudo_uid_str == end && sudo_uid_str[0] != '\0') {
-               printf("child: error: SUDO_UID (%s) could not be converted to an integer\n", sudo_uid_str);
-               EXIT_FAIL();
-       }
-       if (lower_gid == 0) {
-               printf("child: error: less-privileged UID invalid\n");
-               EXIT_FAIL();
-       }
-#endif
-
-       if (setgid(lower_gid) == -1) {
-               printf("child: error: could not change group to %lu\n", lower_gid);
-               EXIT_FAIL();
-       }
-       if (setuid(lower_uid) == -1) {
-               printf("child: error: could not change user to %lu\n", lower_uid);
-               EXIT_FAIL();
-       }
-}
-
 T_DECL(settime_32089962_entitled_root,
        "Verify that root privileges can allow to change the time",
-       T_META_ASROOT(true), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(true), T_META_CHECK_LEAKS(false))
 {
        struct timeval settimeofdaytime;
        struct timeval adj_time;
@@ -120,15 +53,13 @@ T_DECL(settime_32089962_entitled_root,
 
 T_DECL(settime_32089962_entitled_not_root,
        "Verify that the \"com.apple.settime\" entitlement can allow to change the time",
-       T_META_ASROOT(false), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(false), T_META_CHECK_LEAKS(false))
 {
 
        struct timeval settimeofdaytime;
        struct timeval adj_time;
        struct timex ntptime;
 
-       drop_priv();
-
        if (geteuid() == 0){
                 T_SKIP("settime_32089962_entitled_root test requires no root privileges to run.");
         }
@@ -153,7 +84,7 @@ T_DECL(settime_32089962_entitled_not_root,
 
 T_DECL(settimeofday_29193041_entitled_root,
        "Verify that root privileges can allow to change the time",
-       T_META_ASROOT(true), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(true), T_META_CHECK_LEAKS(false))
 {
        struct timeval time;
        long new_time;
@@ -183,13 +114,11 @@ T_DECL(settimeofday_29193041_entitled_root,
 
 T_DECL(settimeofday_29193041_entitled_not_root,
        "Verify that the \"com.apple.settime\" entitlement can allow to change the time",
-       T_META_ASROOT(false), T_META_CHECK_LEAKS(NO))
+       T_META_ASROOT(false), T_META_CHECK_LEAKS(false))
 {
        struct timeval time;
        long new_time;
 
-       drop_priv();
-
        if (geteuid() == 0){
                 T_SKIP("settimeofday_29193041 test requires no root privileges to run.");
         }
index de5eed5d5da5ef70f0743c239f432f6be34e0ecd..cb44aa53f6ea7303eb4e741930cacbe2d50272de 100644 (file)
@@ -7,7 +7,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <errno.h>
-#include <TargetConditionals.h>
 
 static int
 sockv6_open(void)
@@ -97,20 +96,12 @@ T_DECL(socket_bind_35243417,
        T_META_ASROOT(false),
        T_META_CHECK_LEAKS(false))
 {
-#if TARGET_OS_WATCH
-       T_SKIP("socket_bind_35243417 can't run on watch.");
-#else
        alloc_and_bind_ports(1, 65534, 10);
-#endif
 }
 
 T_DECL(socket_bind_35243417_root,
        "bind IPv6 only UDP socket, then bind IPv6 socket.",
        T_META_ASROOT(true))
 {
-#if TARGET_OS_WATCH
-       T_SKIP("socket_bind_35243417_root can't run on watch.");
-#else
        alloc_and_bind_ports(1, 65534, 10);
-#endif
 }
diff --git a/tools/tests/darwintests/socket_bind_35685803.c b/tools/tests/darwintests/socket_bind_35685803.c
new file mode 100644 (file)
index 0000000..d0e22a9
--- /dev/null
@@ -0,0 +1,205 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+
+#include <darwintest.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdbool.h>
+
+static bool debug;
+
+static int
+sock_open_common(int pf, int type)
+{
+       int     s;
+
+       s = socket(pf, type, 0);
+       T_QUIET;
+       T_ASSERT_POSIX_SUCCESS(s, "socket(%d, %d, 0)", pf, type);
+       return (s);
+}
+
+static int
+sock_open(int type)
+{
+       return (sock_open_common(PF_INET, type));
+}
+
+static int
+sock_bind(int s, int port)
+{
+       struct sockaddr_in      sin = {
+               .sin_len = sizeof(sin),
+               .sin_family = AF_INET,
+       };
+
+       sin.sin_port = htons(port);
+       return (bind(s, (const struct sockaddr *)&sin, sizeof(sin)));
+}
+
+static int
+sockv6_open(int type)
+{
+       return (sock_open_common(PF_INET6, type));
+}
+
+static int
+sockv6_bind(int s, int port)
+{
+       struct sockaddr_in6             sin6 = {
+               .sin6_len = sizeof(sin6),
+               .sin6_family = AF_INET6,
+       };
+
+       sin6.sin6_port = htons(port);
+       return (bind(s, (const struct sockaddr *)&sin6, sizeof(sin6)));
+}
+
+static uint16_t
+sock_get_port(int sockfd)
+{
+       int                             error;
+       uint16_t                        p;
+       union sockaddr_in_4_6   sin;
+       socklen_t                       sin_len;
+
+       sin_len = sizeof(sin);
+       bzero(&sin, sin_len);
+       error = getsockname(sockfd, (struct sockaddr *)&sin, &sin_len);
+       T_QUIET;
+       T_EXPECT_POSIX_ZERO(error, "getsockname(%d)", sockfd);
+       if (error != 0) {
+               return (0);
+       }
+       switch (sin.sa.sa_family) {
+       case AF_INET:
+               p = sin.sin.sin_port;
+               break;
+       case AF_INET6:
+               p = sin.sin6.sin6_port;
+               break;
+       default:
+               T_ASSERT_FAIL("unknown address family %d\n",
+                             sin.sa.sa_family);
+               p = 0;
+               break;
+       }
+       return (p);
+}
+
+typedef struct {
+       bool    v6;
+       int             socket_count;
+       int *   socket_list;
+} SocketInfo, * SocketInfoRef;
+
+static void
+bind_sockets(SocketInfoRef info, const char * msg)
+{
+       for (int i = 0; i < info->socket_count; i++) {
+               int             error;
+               uint16_t        port;
+
+               if (info->v6) {
+                       error = sockv6_bind(info->socket_list[i], 0);
+               }
+               else {
+                       error = sock_bind(info->socket_list[i], 0);
+               }
+               port = sock_get_port(info->socket_list[i]);
+               if (debug) {
+                       T_LOG( "%s: fd %d port is %d error %d",
+                              msg, info->socket_list[i], ntohs(port), error);
+               }
+       }
+       return;
+}
+
+static void *
+second_thread(void * arg)
+{
+       SocketInfoRef   info = (SocketInfoRef)arg;
+
+       bind_sockets(info, "second");
+       return (NULL);
+}
+
+static void
+multithreaded_bind_test(bool v6, int socket_count)
+{
+       int             error;
+       SocketInfo      info;
+       int     socket_list[socket_count];
+       pthread_t       thread;
+
+       info.v6 = v6;
+       for (int i = 0; i < socket_count; i++) {
+               if (v6) {
+                       socket_list[i] = sockv6_open(SOCK_STREAM);
+               } else {
+                       socket_list[i] = sock_open(SOCK_STREAM);
+               }
+       }
+       info.socket_count = socket_count;
+       info.socket_list = socket_list;
+       error = pthread_create(&thread, NULL, second_thread, &info);
+       T_QUIET;
+       T_ASSERT_POSIX_ZERO(error, "pthread_create");
+
+       /* compete with second thread */
+       bind_sockets(&info, "main");
+       error = pthread_join(thread, NULL);
+       T_QUIET;
+       T_ASSERT_POSIX_ZERO(error, "pthread_join");
+
+       for (int i = 0; i < socket_count; i++) {
+               error = close(socket_list[i]);
+               T_QUIET;
+               T_ASSERT_POSIX_ZERO(error, "close socket %d", socket_list[i]);
+       }
+}
+
+static void
+run_multithreaded_bind_test(int number_of_runs, bool v6, int socket_count)
+{
+       for (int i = 0; i < number_of_runs; i++) {
+               multithreaded_bind_test(v6, socket_count);
+       }
+       T_PASS("multithreaded_bind_test %s", v6 ? "IPv6" : "IPv4");
+}
+
+T_DECL(socket_bind_35685803,
+       "multithreaded bind IPv4 socket as root",
+       T_META_ASROOT(false),
+       T_META_CHECK_LEAKS(false))
+{
+       run_multithreaded_bind_test(100, false, 100);
+}
+
+T_DECL(socket_bind_35685803_root,
+       "multithreaded bind IPv4 socket",
+       T_META_ASROOT(true))
+{
+       run_multithreaded_bind_test(100, false, 100);
+}
+
+T_DECL(socket_bind_35685803_v6,
+       "multithreaded bind IPv6 socket as root",
+       T_META_ASROOT(false),
+       T_META_CHECK_LEAKS(false))
+{
+       run_multithreaded_bind_test(100, true, 100);
+}
+
+T_DECL(socket_bind_35685803_v6_root,
+       "multithreaded bind IPv6 socket",
+       T_META_ASROOT(true))
+{
+       run_multithreaded_bind_test(100, true, 100);
+}
index 8c6219ab7e66e7e45e8f8fcc903424ff78d220be..2c5b37d5cee321319564ddc22aabdff978490d9f 100644 (file)
@@ -219,16 +219,111 @@ T_DECL(delta, "test delta stackshots")
        });
 }
 
+static void
+expect_instrs_cycles_in_stackshot(void *ssbuf, size_t sslen)
+{
+       kcdata_iter_t iter = kcdata_iter(ssbuf, sslen);
+
+       bool in_task = false;
+       bool in_thread = false;
+       bool saw_instrs_cycles = false;
+       iter = kcdata_iter_next(iter);
+
+       KCDATA_ITER_FOREACH(iter) {
+               switch (kcdata_iter_type(iter)) {
+               case KCDATA_TYPE_CONTAINER_BEGIN:
+                       switch (kcdata_iter_container_type(iter)) {
+                       case STACKSHOT_KCCONTAINER_TASK:
+                               in_task = true;
+                               saw_instrs_cycles = false;
+                               break;
+
+                       case STACKSHOT_KCCONTAINER_THREAD:
+                               in_thread = true;
+                               saw_instrs_cycles = false;
+                               break;
+
+                       default:
+                               break;
+                       }
+                       break;
+
+               case STACKSHOT_KCTYPE_INSTRS_CYCLES:
+                       saw_instrs_cycles = true;
+                       break;
+
+               case KCDATA_TYPE_CONTAINER_END:
+                       if (in_thread) {
+                               T_QUIET; T_EXPECT_TRUE(saw_instrs_cycles, "saw instructions and cycles in thread");
+                               in_thread = false;
+                       } else if (in_task) {
+                               T_QUIET; T_EXPECT_TRUE(saw_instrs_cycles, "saw instructions and cycles in task");
+                               in_task = false;
+                       }
+
+               default:
+                       break;
+               }
+       }
+}
+
+static void
+skip_if_monotonic_unsupported(void)
+{
+       int supported = 0;
+       size_t supported_size = sizeof(supported);
+       int ret = sysctlbyname("kern.monotonic.supported", &supported, &supported_size, 0, 0);
+       if (ret < 0 || !supported) {
+               T_SKIP("monotonic is unsupported");
+       }
+}
+
 T_DECL(instrs_cycles, "test a getting instructions and cycles in stackshot")
 {
+       skip_if_monotonic_unsupported();
+
        struct scenario scenario = {
                .flags = (STACKSHOT_SAVE_LOADINFO | STACKSHOT_INSTRS_CYCLES
                                | STACKSHOT_KCDATA_FORMAT)
        };
 
-       T_LOG("attempting to take stackshot with kernel-only flag");
+       T_LOG("attempting to take stackshot with instructions and cycles");
+       take_stackshot(&scenario, ^(void *ssbuf, size_t sslen) {
+               parse_stackshot(false, ssbuf, sslen);
+               expect_instrs_cycles_in_stackshot(ssbuf, sslen);
+       });
+}
+
+T_DECL(delta_instrs_cycles, "test delta stackshots with instructions and cycles")
+{
+       skip_if_monotonic_unsupported();
+
+       struct scenario scenario = {
+               .flags = (STACKSHOT_SAVE_LOADINFO | STACKSHOT_INSTRS_CYCLES
+                               | STACKSHOT_KCDATA_FORMAT)
+       };
+
+       initialize_thread();
+       T_LOG("taking full stackshot");
        take_stackshot(&scenario, ^(void *ssbuf, size_t sslen) {
+               uint64_t stackshot_time = stackshot_timestamp(ssbuf, sslen);
+
+               T_LOG("taking delta stackshot since time %" PRIu64, stackshot_time);
+
                parse_stackshot(false, ssbuf, sslen);
+               expect_instrs_cycles_in_stackshot(ssbuf, sslen);
+
+               struct scenario delta_scenario = {
+                       .flags = (STACKSHOT_SAVE_LOADINFO | STACKSHOT_INSTRS_CYCLES
+                                       | STACKSHOT_KCDATA_FORMAT
+                                       | STACKSHOT_COLLECT_DELTA_SNAPSHOT),
+                       .since_timestamp = stackshot_time
+               };
+
+               take_stackshot(&delta_scenario, ^(void *dssbuf, size_t dsslen) {
+                       parse_stackshot(true, dssbuf, dsslen);
+                       expect_instrs_cycles_in_stackshot(dssbuf, dsslen);
+               });
        });
 }
 
index a1395618cc856580895a9612153bbfa17d1693c6..bf4f3ae57bc968e426d4c6e5e5f83616aa66d1da 100644 (file)
 #include <sys/types.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <TargetConditionals.h>
+
+#if !TARGET_OS_EMBEDDED
+#include <pcre.h>
+#endif
+
 
 T_GLOBAL_META(
         T_META_NAMESPACE("xnu.scheduler"),
@@ -56,8 +62,8 @@ static mach_port_t recv = MACH_PORT_NULL;
 static void *
 take_stackshot(uint32_t extra_flags, uint64_t since_timestamp)
 {
-       void * stackshot;
-       int ret, retries;
+       void * stackshot = NULL;
+       int ret = 0;
        uint32_t stackshot_flags = STACKSHOT_SAVE_LOADINFO |
                                        STACKSHOT_GET_GLOBAL_MEM_STATS |
                                        STACKSHOT_SAVE_IMP_DONATION_PIDS |
@@ -82,7 +88,7 @@ take_stackshot(uint32_t extra_flags, uint64_t since_timestamp)
                T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Setting prev snapshot time on stackshot config");
        }
 
-       for (retries = NUMRETRIES; retries > 0; retries--) {
+       for (int retries = NUMRETRIES; retries > 0; retries--) {
                ret = stackshot_capture_with_config(stackshot);
                T_QUIET; T_ASSERT_TRUE(ret == 0 || ret == EBUSY || ret == ETIMEDOUT,
                                "Attempting to take stackshot (error %d)...", ret);
@@ -94,16 +100,74 @@ take_stackshot(uint32_t extra_flags, uint64_t since_timestamp)
        return stackshot;
 }
 
+static void
+save_stackshot(void *stackshot, const char *filename)
+{
+       void *buf = stackshot_config_get_stackshot_buffer(stackshot);
+       T_QUIET; T_ASSERT_NOTNULL(buf, "buf");
+       size_t size = stackshot_config_get_stackshot_size(stackshot);
+       FILE *f = fopen(filename, "w");
+       T_QUIET; T_ASSERT_NOTNULL(f, "f");
+       fwrite(buf, size, 1, f);
+       fclose(f);
+}
+
+static
+void check_python(void *stackshot, const char *fmt, ...)
+{
+       save_stackshot(stackshot, "/tmp/ss");
+
+#if !TARGET_OS_EMBEDDED
+       va_list args;
+       va_start(args, fmt);
+       char *re_string = NULL;
+       vasprintf(&re_string, fmt, args);
+       va_end(args);
+       T_QUIET; T_ASSERT_NOTNULL(re_string, "vasprintf");
+
+       const char *pcreErrorStr;
+       int pcreErrorOffset;
+       pcre *re = pcre_compile(re_string, 0, &pcreErrorStr, &pcreErrorOffset, NULL);
+       T_QUIET; T_ASSERT_NOTNULL(re, "pcre_compile");
+
+       bool found = false;
+       FILE *p = popen("/usr/local/bin/kcdata --pretty /tmp/ss", "r");
+       T_QUIET; T_ASSERT_NOTNULL(p, "popen");
+       while (1) {
+               char *line = NULL;
+               size_t linecap = 0;
+               ssize_t linesize = getline(&line, &linecap, p);
+               if (linesize < 0) {
+                       if (line)
+                               free(line);
+                       break;
+               }
+               int pcre_ret = pcre_exec(re, NULL, line, strlen(line), 0, 0, NULL, 0);
+               if (pcre_ret == 0){
+                       T_LOG("line: %s", line);
+                       found = true;
+               }
+               free(line);
+       }
+       T_EXPECT_TRUE(found, "found the waitinfo in kcdata.py output");
+       pclose(p);
+       pcre_free(re);
+       free(re_string);
+#endif
+}
+
+
 // waitinfo can be NULL, but len must be non-null and point to the length of the waitinfo array.
 // when the function returns, len will be set to the number of waitinfo structs found in the stackshot.
 static void
 find_blocking_info(void * stackshot, struct stackshot_thread_waitinfo *waitinfo, int *len)
 {
-       void *buf;
-       uint32_t t, buflen;
+       void *buf = NULL;
+       uint32_t t = 0;
+       uint32_t buflen = 0;
        NSError *error = nil;
-       NSMutableDictionary *parsed_container;
-       NSArray *parsed_waitinfo;
+       NSMutableDictionary *parsed_container = nil;
+       NSArray *parsed_waitinfo = nil;
 
        T_QUIET; T_ASSERT_NOTNULL(len, "Length pointer shouldn't be NULL");
        int oldlen = *len;
@@ -164,7 +228,7 @@ find_blocking_info(void * stackshot, struct stackshot_thread_waitinfo *waitinfo,
  * returns 1. */
 static int kmutex_action(int action)
 {
-       int ret;
+       int ret = 0;
        if (action == KMUTEX_SYSCTL_CHECK_EXISTS) {
                ret = sysctlbyname(krwlck_ctl, NULL, NULL, NULL, 0);
                return !(ret == -1);
@@ -197,8 +261,8 @@ static int kmutex_action(int action)
 static void
 sysctl_kmutex_test_match(uint64_t context)
 {
-       int ret;
-       unsigned long long unslid_kmutex_address;
+       int ret = 0;
+       unsigned long long unslid_kmutex_address = 0;
        size_t addrsize = sizeof(unslid_kmutex_address);
 
        ret = sysctlbyname(kmutex_ctl, &unslid_kmutex_address, &addrsize, NULL, 0);
@@ -242,7 +306,7 @@ msg_send_helper(mach_port_t remote_port)
 static void
 msg_recv_helper(mach_port_t local_port)
 {
-       int ret;
+       int ret = 0;
        mach_msg_size_t size = 2*PAGE_SIZE;
        mach_msg_header_t * msg = NULL;
         ret = vm_allocate(mach_task_self(),
@@ -272,7 +336,7 @@ msg_recv_helper(mach_port_t local_port)
 static int
 krwlck_action(int action)
 {
-       int ret;
+       int ret = 0;
        if (action == KRWLCK_SYSCTL_CHECK_EXISTS) {
                ret = sysctlbyname(krwlck_ctl, NULL, NULL, NULL, 0);
                return !(ret == -1);
@@ -311,8 +375,8 @@ krwlck_action(int action)
 static void
 sysctl_krwlck_test_match(uint64_t context)
 {
-       int ret;
-       unsigned long long unslid_krwlck_address;
+       int ret = 0;
+       unsigned long long unslid_krwlck_address = 0;
        size_t addrsize = sizeof(unslid_krwlck_address);
 
        ret = sysctlbyname(krwlck_ctl, &unslid_krwlck_address, &addrsize, NULL, 0);
@@ -425,10 +489,10 @@ pthread_cond_blocking_thread(void * arg)
 static void
 test_kmutex_blocking(void)
 {
-       int ret;
+       int ret = 0;
        int len = 2;
-       struct stackshot_thread_waitinfo waitinfo[len];
-       uint64_t thread_id;
+       struct stackshot_thread_waitinfo waitinfo[2] = { { 0 }, { 0 } };
+       uint64_t thread_id = 0;
        pthread_t grabbing, waiting;
 
        T_LOG("Starting %s", __FUNCTION__);
@@ -440,6 +504,12 @@ test_kmutex_blocking(void)
        sleep(3); // give (lots of) time for thread to give up spinning on lock
 
        void * stackshot = take_stackshot(STACKSHOT_THREAD_WAITINFO, 0);
+
+       ret = pthread_threadid_np(waiting, &thread_id); // this is the thread that currently holds the kernel mutex
+       T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Getting integer value of thread id");
+
+       check_python(stackshot, "thread \\d+: semaphore port \\w+ with unknown owner");
+
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
 
        T_EXPECT_EQ(len, 2, "There should only be two blocking threads");
@@ -448,10 +518,10 @@ test_kmutex_blocking(void)
                if (curr->wait_type == kThreadWaitSemaphore)
                        continue;
                T_EXPECT_EQ(curr->wait_type, kThreadWaitKernelMutex, "Wait type should match expected KernelMutex value");
-               ret = pthread_threadid_np(waiting, &thread_id); // this is the thread that currently holds the kernel mutex
-               T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Getting integer value of thread id");
                T_EXPECT_EQ(curr->owner, thread_id, "Thread ID of blocking thread should match 'owner' field in stackshot");
                sysctl_kmutex_test_match(curr->context);
+
+               check_python(stackshot, "thread \\d+: kernel mutex %llx owned by thread %lld", curr->context, thread_id);
        }
 
        kmutex_action(KMUTEX_SYSCTL_SIGNAL); // waiting thread should now unblock.
@@ -467,11 +537,11 @@ test_kmutex_blocking(void)
 static void
 test_semaphore_blocking(void)
 {
-       int ret;
+       int ret = 0;
        semaphore_t sem;
-       struct stackshot_thread_waitinfo waitinfo;
+       struct stackshot_thread_waitinfo waitinfo = { 0 };
        int len = 1;
-       uint64_t pid;
+       uint64_t pid = 0;
 
        T_LOG("Starting %s", __FUNCTION__);
        ret = semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, 0);
@@ -490,6 +560,8 @@ test_semaphore_blocking(void)
        pid = (uint64_t)getpid();
        T_EXPECT_EQ(waitinfo.owner, pid, "Owner value should match process ID");
 
+       check_python(stackshot, "thread \\d+: semaphore port \\w+ owned by pid %d", (int)pid);
+
        ret = semaphore_signal(sem);
        T_QUIET; T_ASSERT_MACH_SUCCESS(ret, "Signalling semaphore");
        ret = pthread_join(tid, NULL);
@@ -503,10 +575,10 @@ test_semaphore_blocking(void)
 static void
 test_mach_msg_blocking(void)
 {
-       int ret;
+       int ret = 0;
        pthread_t tid;
-       void *stackshot;
-       struct stackshot_thread_waitinfo waitinfo;
+       void *stackshot = NULL;
+       struct stackshot_thread_waitinfo waitinfo = { 0 };
        int len = 1;
 
        T_LOG("Starting %s", __FUNCTION__);
@@ -528,6 +600,9 @@ test_mach_msg_blocking(void)
 
        T_EXPECT_EQ(len, 1, "Only one blocking thread should exist");
        T_EXPECT_EQ(waitinfo.wait_type, kThreadWaitPortReceive, "Wait type should match expected PortReceive value");
+
+       check_python(stackshot, "thread \\d+: mach_msg receive on port \\w+ name %llx", (long long)send);
+
        stackshot_config_dealloc(stackshot);
 
        msg_send_helper(send); // ping! msg_blocking_thread will now try to send us stuff, and block until we receive.
@@ -537,6 +612,9 @@ test_mach_msg_blocking(void)
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
        T_EXPECT_EQ(len, 1, "Only one blocking thread should exist");
        T_EXPECT_EQ(waitinfo.wait_type, kThreadWaitPortSend, "Wait type should match expected PortSend value");
+
+       check_python(stackshot, "thread \\d+: mach_msg send on port \\w+ owned by pid %d", (int)getpid());
+
        stackshot_config_dealloc(stackshot);
 
        msg_recv_helper(recv); // thread should block until we receive one of its messages
@@ -547,13 +625,13 @@ test_mach_msg_blocking(void)
 static void
 test_ulock_blocking(void)
 {
-       int ret;
-       void *stackshot;
-       uint64_t thread_id;
+       int ret = 0;
+       void *stackshot = NULL;
+       uint64_t thread_id = 0;
        pthread_t tid;
        struct os_unfair_lock_s ouls = OS_UNFAIR_LOCK_INIT;
        os_unfair_lock_t oul = &ouls;
-       struct stackshot_thread_waitinfo waitinfo;
+       struct stackshot_thread_waitinfo waitinfo = { 0 };
        int len = 1;
 
        T_LOG("Starting %s", __FUNCTION__);
@@ -563,10 +641,10 @@ test_ulock_blocking(void)
        sleep(3); // give time for thread to spawn, fall back to kernel for contention, and block
 
        stackshot = take_stackshot(STACKSHOT_THREAD_WAITINFO, 0);
+
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
        T_EXPECT_EQ(len, 1, "Only one blocking thread should exist");
        T_EXPECT_EQ(waitinfo.wait_type, kThreadWaitUserLock, "Wait type should match expected UserLock value");
-       stackshot_config_dealloc(stackshot);
 
        os_unfair_lock_unlock(oul);
        ret = pthread_join(tid, NULL); // wait for thread to unblock and exit
@@ -575,18 +653,21 @@ test_ulock_blocking(void)
        ret = pthread_threadid_np(NULL, &thread_id); // this thread is the "owner" of the ulock
        T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Getting integer value of thread id");
        T_EXPECT_EQ(waitinfo.owner, thread_id, "Thread ID of blocking thread should match 'owner' field in stackshot");
+
+       check_python(stackshot, "thread \\d+: unfair lock \\w+ owned by thread %lld", thread_id);
+       stackshot_config_dealloc(stackshot);
        return;
 }
 
 static void
 test_krwlock_blocking(void)
 {
-       int ret;
-       void *stackshot;
-       uint64_t thread_id;
+       int ret = 0;
+       void *stackshot = NULL;
+       uint64_t thread_id = 0;
        pthread_t waiting, grabbing;
        int len = 2;
-       struct stackshot_thread_waitinfo waitinfo[len];
+       struct stackshot_thread_waitinfo waitinfo[2] = { { 0 }, { 0 } };
 
        T_LOG("Starting %s", __FUNCTION__);
        // this thread should spawn, acquire a kernel rwlock for write, and then wait on a semaphore
@@ -599,6 +680,9 @@ test_krwlock_blocking(void)
        sleep(1); // give time for thread to block
 
        stackshot = take_stackshot(STACKSHOT_THREAD_WAITINFO, 0);
+
+       check_python(stackshot, "thread \\d+: semaphore port \\w+ with unknown owner");
+
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
 
        T_EXPECT_EQ(len, 2, "There should only be two blocking threads");
@@ -609,10 +693,14 @@ test_krwlock_blocking(void)
                T_EXPECT_EQ(curr->wait_type, kThreadWaitKernelRWLockRead, "Wait type should match expected KRWLockRead value");
                sysctl_krwlck_test_match(curr->context);
 
+               check_python(stackshot, "thread \\d+: krwlock %llx for reading", curr->context);
+
 #if KRWLCK_STORES_EXCL_OWNER /* A future planned enhancement */
                ret = pthread_threadid_np(waiting, &thread_id); // this is the thread that currently holds the kernel mutex
                T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Getting integer value of thread id");
                T_EXPECT_EQ(curr->owner, thread_id, "Thread ID of blocking thread should match 'owner' field in stackshot");
+#else
+               (void)thread_id; // suppress compiler warning about unused variable
 #endif /* RWLCK_STORES_EXCL_OWNER */
        }
 
@@ -625,25 +713,32 @@ test_krwlock_blocking(void)
        stackshot_config_dealloc(stackshot);
 }
 
+
 static void
 test_pthread_mutex_blocking(void)
 {
-       int ret;
-       void *stackshot;
-       uint64_t thread_id;
+       int ret = 0;
+       void *stackshot = NULL;
+       uint64_t thread_id = 0;
        pthread_t tid;
-       struct stackshot_thread_waitinfo waitinfo;
+       struct stackshot_thread_waitinfo waitinfo = { 0 };
        pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
        int len = 1;
 
        T_LOG("Starting %s", __FUNCTION__);
 
+       ret = pthread_threadid_np(NULL, &thread_id); // this thread is the "owner" of the mutex
+       T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Getting integer value of thread id");
+
        pthread_mutex_lock(&mtx);
        ret = pthread_create(&tid, NULL, pthread_mutex_blocking_thread, (void*)&mtx);
        T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Creating pthread mutex blocking thread");
        sleep(2); // give time for thread to block
 
        stackshot = take_stackshot(STACKSHOT_THREAD_WAITINFO, 0);
+
+       check_python(stackshot, "thread \\d+: pthread mutex %llx owned by thread %lld", &mtx, thread_id);
+
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
        T_EXPECT_EQ(len, 1, "Only one blocking thread should exist");
        T_EXPECT_EQ(waitinfo.wait_type, kThreadWaitPThreadMutex,
@@ -653,8 +748,7 @@ test_pthread_mutex_blocking(void)
        pthread_mutex_unlock(&mtx);
        ret = pthread_join(tid, NULL); // wait for thread to unblock and exit
 
-       ret = pthread_threadid_np(NULL, &thread_id); // this thread is the "owner" of the mutex
-       T_QUIET; T_ASSERT_POSIX_ZERO(ret, "Getting integer value of thread id");
+
        T_EXPECT_EQ(waitinfo.owner, thread_id,
                        "Thread ID of blocking thread should match 'owner' field in stackshot");
        T_EXPECT_EQ(waitinfo.context, (uint64_t)&mtx,
@@ -664,10 +758,10 @@ test_pthread_mutex_blocking(void)
 static void
 test_pthread_rwlck_blocking(void)
 {
-       int ret;
-       void *stackshot;
+       int ret = 0;
+       void *stackshot = NULL;
        pthread_t tid;
-       struct stackshot_thread_waitinfo waitinfo;
+       struct stackshot_thread_waitinfo waitinfo = { 0 };
        pthread_rwlock_t rwlck = PTHREAD_RWLOCK_INITIALIZER;
        int len = 1;
 
@@ -678,6 +772,9 @@ test_pthread_rwlck_blocking(void)
        sleep(2);
 
        stackshot = take_stackshot(STACKSHOT_THREAD_WAITINFO, 0);
+
+       check_python(stackshot, "thread \\d+: pthread rwlock %llx for reading", (long long)&rwlck);
+
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
        T_EXPECT_EQ(len, 1, "Only one blocking thread should exist");
        T_EXPECT_EQ(waitinfo.wait_type, kThreadWaitPThreadRWLockRead,
@@ -690,14 +787,16 @@ test_pthread_rwlck_blocking(void)
                        "Userspace address of rwlck should match 'context' field in stackshot");
 }
 
+
+
 static void
 test_pthread_cond_blocking(void)
 {
-       int ret;
-       void *stackshot;
+       int ret = 0;
+       void *stackshot = NULL;
        pthread_t tid;
        pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-       struct stackshot_thread_waitinfo waitinfo;
+       struct stackshot_thread_waitinfo waitinfo = { 0 };
        int len = 1;
 
        T_LOG("Starting %s", __FUNCTION__);
@@ -706,6 +805,9 @@ test_pthread_cond_blocking(void)
        sleep(2);
 
        stackshot = take_stackshot(STACKSHOT_THREAD_WAITINFO, 0);
+
+       check_python(stackshot, "thread \\d+: pthread condvar %llx", (long long)&cond);
+
        find_blocking_info(stackshot, (struct stackshot_thread_waitinfo *)&waitinfo, &len);
        T_EXPECT_EQ(len, 1, "Only one blocking thread should exist");
        T_EXPECT_EQ(waitinfo.wait_type, kThreadWaitPThreadCondVar,
index 906243a56cb85c5b3151fa63066f5ae5130cffcb..cb77c304f7508f812d94fee45dc56ea6cc987dc5 100644 (file)
@@ -6,6 +6,7 @@
 #include <mach/policy.h>
 #include <mach/task_info.h>
 #include <mach/thread_info.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
@@ -712,6 +713,220 @@ test_task_basic_info(enum info_kind kind)
 #undef AFTER
 }
 
+T_DECL(test_sigcont_task_suspend_resume,
+       "test to verify that SIGCONT on task_suspend()-ed process works",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       T_SETUPBEGIN;
+       int is_dev = is_development_kernel();
+       T_QUIET;
+       T_ASSERT_TRUE(is_dev, "verify development kernel is running");
+       T_SETUPEND;
+
+       mach_task_basic_info_data_t mach_basic_info_data;
+       task_info_t info_data = (task_info_t)&mach_basic_info_data;
+
+       task_debug_info_internal_data_t debug_info;
+       mach_msg_type_number_t debug_count = TASK_DEBUG_INFO_INTERNAL_COUNT;
+
+       kern_return_t kr;
+       int posix_ret;
+       mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
+       task_flavor_t flavor         = MACH_TASK_BASIC_INFO;
+       integer_t suspend_count;
+       integer_t debug_suspend_count;
+       pid_t child_pid = 0;
+       mach_port_name_t child_task;
+       /*for dt_waitpid*/
+       int timeout     = 5;
+       int exit_status = 0;
+       int signal_no   = 0;
+
+       child_pid = fork();
+
+       T_ASSERT_POSIX_SUCCESS(child_pid, "verify process can be forked");
+
+       if (child_pid == 0) {
+               /*
+                * This will suspend the child process.
+                */
+               kr = task_suspend(mach_task_self());
+
+               /*
+                * When child resumes, it exits immediately
+                */
+
+               exit(kr);
+       }
+
+       /*
+        * Wait for the child process to suspend itself.
+        */
+       sleep(1);
+
+       kr = task_for_pid(mach_task_self(), child_pid, &child_task);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_for_pid succeeded.  check sudo if failed");
+
+       /*
+        * Verify the suspend_count for child and resume it.
+        */
+
+       kr = task_info(child_task, flavor, info_data, &count);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_info call succeeded");
+
+       suspend_count = (integer_t)(info_get(INFO_MACH, GET_SUSPEND_COUNT, info_data));
+       T_ASSERT_EQ(suspend_count, 1, "verify task_info shows correct suspend_count (1) (actually user stop count) ");
+
+       kr = task_info(child_task, TASK_DEBUG_INFO_INTERNAL, (task_info_t)&debug_info, &debug_count);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_info call succeeded");
+
+       debug_suspend_count = debug_info.suspend_count;
+       T_ASSERT_EQ(debug_info.suspend_count, 1, "verify debug_info shows correct suspend_count(1)");
+
+       posix_ret = kill(child_pid, SIGCONT);
+       T_ASSERT_POSIX_SUCCESS(posix_ret, "verify signal call succeeded");
+
+       /*
+        * reap kr from task_suspend call in child
+        */
+       dt_waitpid(child_pid, &exit_status, &signal_no, timeout);
+
+       T_ASSERT_EQ(signal_no, 0, "child should be resumed and exit without signal");
+       T_ASSERT_EQ(exit_status, 0, "child should exit with 0");
+
+}
+
+T_DECL(test_sigcont_task_suspend2_resume,
+       "test to verify that SIGCONT on task_suspend2()-ed process doesn't work",
+       T_META_ASROOT(true),
+       T_META_LTEPHASE(LTE_POSTINIT))
+{
+       T_SETUPBEGIN;
+       int is_dev = is_development_kernel();
+       T_QUIET;
+       T_ASSERT_TRUE(is_dev, "verify development kernel is running");
+       T_SETUPEND;
+
+       mach_task_basic_info_data_t mach_basic_info_data;
+       task_info_t info_data = (task_info_t)&mach_basic_info_data;
+
+       task_debug_info_internal_data_t debug_info;
+       mach_msg_type_number_t debug_count = TASK_DEBUG_INFO_INTERNAL_COUNT;
+
+       kern_return_t kr;
+       int posix_ret;
+       mach_msg_type_number_t count  = MACH_TASK_BASIC_INFO_COUNT;
+       task_flavor_t flavor          = MACH_TASK_BASIC_INFO;
+       integer_t suspend_count       = 0;
+       integer_t debug_suspend_count = 0;
+       pid_t child_pid               = 0;
+       mach_port_name_t child_task;
+       task_suspension_token_t child_token = 0xFFFFF;
+
+       /*
+        * for dt_waitpid
+        * We expect the test to fail right now, so I've set timeout to
+        * be shorter than we may want it to be when the issue is fixed
+        */
+       int timeout     = 1;
+       int exit_status = 0;
+       int signal_no   = 0;
+
+       /* for pipe */
+       int fd[2];
+       pipe(fd);
+       int pipe_msg = 0;
+
+       child_pid = fork();
+
+       T_ASSERT_POSIX_SUCCESS(child_pid, "verify process can be forked %d", child_pid);
+
+       if (child_pid == 0) {
+               close(fd[1]);
+               T_LOG("Waiting to read from parent...");
+               read(fd[0], &pipe_msg, sizeof(pipe_msg));
+               T_LOG("Done reading from parent, about to exit...");
+               exit(0);
+       }
+       /*
+        * Wait for child to fork and block on read
+        */
+       sleep(1);
+
+       close(fd[0]);
+
+       kr = task_for_pid(mach_task_self(), child_pid, &child_task);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_for_pid succeeded.  check sudo if failed");
+
+       kr = task_info(child_task, TASK_DEBUG_INFO_INTERNAL, (task_info_t)&debug_info, &debug_count);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_info call succeeded");
+
+       debug_suspend_count = debug_info.suspend_count;
+       T_EXPECT_EQ(debug_suspend_count, 0, "verify debug_info shows correct (true) suspend_count(0)");
+
+       kr = task_suspend2(child_task, &child_token);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_suspend2 call succeeded");
+
+       kr = task_info(child_task, TASK_DEBUG_INFO_INTERNAL, (task_info_t)&debug_info, &debug_count);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_info call succeeded");
+
+       debug_suspend_count = debug_info.suspend_count;
+       T_ASSERT_EQ(debug_suspend_count, 1, "verify debug_info shows correct (true) suspend_count(1)");
+
+       /*
+        * Verify the suspend_count for child and resume it.
+        */
+
+       kr = task_info(child_task, flavor, info_data, &count);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_info call succeeded");
+
+       suspend_count = (integer_t)(info_get(INFO_MACH, GET_SUSPEND_COUNT, info_data));
+       T_EXPECT_EQ(suspend_count, 1, "verify task_info shows correct (user_stop_count) suspend_count (1)");
+
+       posix_ret = kill(child_pid, SIGCONT);
+       T_ASSERT_POSIX_SUCCESS(posix_ret, "verify signal call succeeded");
+
+       kr = task_info(child_task, TASK_DEBUG_INFO_INTERNAL, (task_info_t)&debug_info, &debug_count);
+       T_EXPECT_MACH_SUCCESS(kr, "verify task_info call succeeded");
+
+       debug_suspend_count = debug_info.suspend_count;
+       T_EXPECTFAIL_WITH_RADAR(33166654);
+       T_EXPECT_EQ(debug_suspend_count, 1, "verify debug_info shows correct (true) suspend_count (1)");
+
+       suspend_count = (integer_t)(info_get(INFO_MACH, GET_SUSPEND_COUNT, info_data));
+       T_ASSERT_EQ(suspend_count, 1, "verify task_info shows correct (user_stop_count) suspend_count (1) after SIG_CONT");
+
+       kr = task_resume(child_task);
+       T_EXPECTFAIL_WITH_RADAR(33166654);
+       T_EXPECT_MACH_SUCCESS(kr, "verify task_resume succeeded");
+
+       /*
+        * reap kr from task_suspend call in child
+        */
+
+       dt_waitpid(child_pid, &exit_status, &signal_no, timeout);
+
+       T_ASSERT_EQ(signal_no, SIG_DT_TIMEOUT, "dt_waitpid timed out as expected");
+
+       // Resume properly using token and then wait
+
+       kr = task_resume2(child_token);
+       T_EXPECTFAIL_WITH_RADAR(33166654);
+       T_ASSERT_MACH_SUCCESS(kr, "verify task_resume2 succeeded");
+
+       write(fd[1], &pipe_msg, sizeof(pipe_msg));
+
+       /*
+        * reap kr from task_suspend call in child
+        */
+       dt_waitpid(child_pid, &exit_status, &signal_no, timeout);
+
+       T_ASSERT_EQ(signal_no, 0, "child should be resumed and no signal should be returned");
+       T_ASSERT_EQ(exit_status, 0, "child should exit with 0");
+
+}
+
 uint64_t
 info_get(enum info_kind kind, enum info_get get, void * data)
 {
index cebd042d09a92c31eb6d9daa0b06b7c60b4e05a4..1c7eb3f6ca56ac4be1cddbeecff9edc1a6323641 100644 (file)
@@ -21,26 +21,25 @@ T_DECL(thread_group_set, "Checks that new threads get a THREAD_GROUP_SET tracepo
        __block int seen_new_thread = 0, __block seen_thread_group_set = 0;
 
        ktrace_machine_t machine = ktrace_machine_create_current();
-       T_ASSERT_NOTNULL(machine, "ktrace_get_machine");
+       T_WITH_ERRNO; T_ASSERT_NOTNULL(machine, "ktrace_get_machine");
 
        bool has_tg = false;
        if (ktrace_machine_has_thread_groups(machine, &has_tg) || !has_tg) {
                T_SKIP("thread groups not supported on this system");
        }
+       ktrace_machine_destroy(machine);
 
        ktrace_session_t session = ktrace_session_create();
-       T_ASSERT_NOTNULL(session, "ktrace_session_create");
+       T_WITH_ERRNO; T_ASSERT_NOTNULL(session, "ktrace_session_create");
 
        ktrace_set_interactive(session);
 
        ktrace_set_completion_handler(session, ^{
+               ktrace_session_destroy(session);
                T_ASSERT_TRUE(seen_new_thread, "seen new thread tracepoint");
                T_END;
        });
 
-       T_EXPECT_POSIX_SUCCESS(pthread_create(&thread, NULL, newthread, NULL), "pthread_create");
-       T_EXPECT_POSIX_SUCCESS(pthread_detach(thread), "pthread_detach");
-
        ktrace_events_single(session, TEST_EVENTID, ^(__unused ktrace_event_t e) {
                T_EXPECT_TRUE(seen_thread_group_set, "seen THREAD_GROUP_SET tracepoint");
                seen_new_thread = 1;
@@ -48,7 +47,7 @@ T_DECL(thread_group_set, "Checks that new threads get a THREAD_GROUP_SET tracepo
        });
 
        ktrace_events_single(session, MACHDBG_CODE(DBG_MACH_THREAD_GROUP, MACH_THREAD_GROUP_SET), ^(ktrace_event_t e) {
-               T_EXPECT_GT(e->arg3, 0, "tid on THREAD_GROUP_SET");
+               T_EXPECT_GT(e->arg3, (uintptr_t)0, "tid on THREAD_GROUP_SET");
                seen_thread_group_set = 1;
        });
 
@@ -58,5 +57,8 @@ T_DECL(thread_group_set, "Checks that new threads get a THREAD_GROUP_SET tracepo
 
        T_ASSERT_POSIX_SUCCESS(ktrace_start(session, dispatch_get_main_queue()), "ktrace_start");
 
+       T_EXPECT_POSIX_SUCCESS(pthread_create(&thread, NULL, newthread, NULL), "pthread_create");
+       T_EXPECT_POSIX_SUCCESS(pthread_detach(thread), "pthread_detach");
+
        dispatch_main();
 }
index bcda28f9e0e0c815a57dbf07b5d96a7a4455713f..d5baad67fe0b8b93596542c52e2fcb4cf3f0d468 100644 (file)
@@ -34,6 +34,12 @@ T_DECL(utimensat, "Try various versions of utimensat")
 {
        T_SETUPBEGIN;
        T_ASSERT_POSIX_ZERO(chdir(dt_tmpdir()), NULL);
+       // Skip the test if the current working directory is not on APFS.
+       struct statfs sfs = { 0 };
+       T_QUIET; T_ASSERT_POSIX_SUCCESS(statfs(".", &sfs), NULL);
+       if (memcmp(&sfs.f_fstypename[0], "apfs", strlen("apfs")) != 0) {
+               T_SKIP("utimensat is APFS-only, but working directory is non-APFS");
+       }
        T_SETUPEND;
 
        struct stat pre_st, post_st;
diff --git a/tools/tests/darwintests/verify_kalloc_config.c b/tools/tests/darwintests/verify_kalloc_config.c
new file mode 100644 (file)
index 0000000..14ce3c9
--- /dev/null
@@ -0,0 +1,68 @@
+#include <string.h>
+#include <stdlib.h>
+#include <mach/mach.h>
+#include <mach_debug/mach_debug.h>
+#include <darwintest.h>
+
+T_GLOBAL_META(
+       T_META_NAMESPACE("xnu.vm"),
+       T_META_CHECK_LEAKS(false)
+);
+
+static void run_test(void);
+
+static void run_test(void)
+{
+       kern_return_t kr;
+       uint64_t size, i;
+       mach_zone_name_t *name = NULL;
+       unsigned int nameCnt = 0;
+       mach_zone_info_t *info = NULL;
+       unsigned int infoCnt = 0;
+       mach_memory_info_t *wiredInfo = NULL;
+       unsigned int wiredInfoCnt = 0;
+       const char kalloc_str[] = "kalloc.";
+
+       kr = mach_memory_info(mach_host_self(),
+                       &name, &nameCnt, &info, &infoCnt,
+                       &wiredInfo, &wiredInfoCnt);
+       T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_memory_info");
+       T_QUIET; T_ASSERT_EQ(nameCnt, infoCnt, "zone name and info counts don't match");
+
+       /* Match the names of the kalloc zones against their element sizes. */
+       for (i = 0; i < nameCnt; i++) {
+               if (strncmp(name[i].mzn_name, kalloc_str, strlen(kalloc_str)) == 0) {
+                       size = strtoul(&(name[i].mzn_name[strlen(kalloc_str)]), NULL, 10);
+                       T_LOG("ZONE NAME: %-25s ELEMENT SIZE: %llu", name[i].mzn_name, size);
+                       T_QUIET; T_ASSERT_EQ(size, info[i].mzi_elem_size, "kalloc zone name and element size don't match");
+               }
+       }
+
+       if ((name != NULL) && (nameCnt != 0)) {
+               kr = vm_deallocate(mach_task_self(), (vm_address_t) name,
+                               (vm_size_t) (nameCnt * sizeof *name));
+               T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate name");
+       }
+
+       if ((info != NULL) && (infoCnt != 0)) {
+               kr = vm_deallocate(mach_task_self(), (vm_address_t) info,
+                               (vm_size_t) (infoCnt * sizeof *info));
+               T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate info");
+       }
+
+       if ((wiredInfo != NULL) && (wiredInfoCnt != 0)) {
+               kr = vm_deallocate(mach_task_self(), (vm_address_t) wiredInfo,
+                               (vm_size_t) (wiredInfoCnt * sizeof *wiredInfo));
+               T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate wiredInfo");
+       }
+
+       T_END;
+}
+
+T_DECL( verify_kalloc_config,
+               "verifies that the kalloc zones are configured correctly",
+               T_META_ASROOT(true))
+{
+       run_test();
+}
+
diff --git a/tools/tests/darwintests/xnu_quick_test_getsetpriority.c b/tools/tests/darwintests/xnu_quick_test_getsetpriority.c
new file mode 100644 (file)
index 0000000..ec62af5
--- /dev/null
@@ -0,0 +1,40 @@
+#include <darwintest.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+T_GLOBAL_META(T_META_NAMESPACE("xnu.quicktest"), T_META_CHECK_LEAKS(false));
+
+T_DECL(getpriority_setpriority, "Tests getpriority and setpriority system calls", T_META_ASROOT(true))
+{
+       int my_priority;
+       int my_new_priority;
+
+       /* getpriority returns scheduling priority so -1 is a valid value */
+       errno       = 0;
+       my_priority = getpriority(PRIO_PROCESS, 0);
+
+       T_WITH_ERRNO;
+       T_ASSERT_FALSE(my_priority == -1 && errno != 0, "Verify getpriority is successful", NULL);
+
+       /* change scheduling priority*/
+       my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN);
+
+       T_WITH_ERRNO;
+       T_ASSERT_POSIX_SUCCESS(setpriority(PRIO_PROCESS, 0, my_new_priority), "Change scheduling priority", NULL);
+
+       /* verify change */
+       errno       = 0;
+       my_priority = getpriority(PRIO_PROCESS, 0);
+       T_WITH_ERRNO;
+       T_ASSERT_FALSE(my_priority == -1 && errno != 0, "Verify getpriority change is successful", NULL);
+
+       T_WITH_ERRNO;
+       T_ASSERT_EQ(my_priority, my_new_priority, "Verify setpriority correctly set scheduling priority", NULL);
+
+       /* reset scheduling priority */
+       T_WITH_ERRNO;
+       T_ASSERT_POSIX_SUCCESS(setpriority(PRIO_PROCESS, 0, 0), "Reset scheduling priority", NULL);
+}
diff --git a/tools/tests/libMicro/AppleReadMe b/tools/tests/libMicro/AppleReadMe
deleted file mode 100755 (executable)
index 8b38345..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-Mac OS X specific notes
-
-*** Instructions before Starting libMicro ***
-
-# Disable Open directory and LDAP using Directory Utility app
-# Turn off airport
-# Turn off spotlight. In terminal, execute the following:
-  launchctl unload /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
-# Turn off Time Machine in System Preferences
-# Wait at least 2 minutes after boot to desktop for boot cache to settle down
-   
-*** Make and run quickstart ***
-
-       make
-       ./bench >output.txt
-runs the libMicro test suite excluding the lmbench tests and gives you a text file named output.txt with the results of one run.
-       
-
-       ./multiview output1.txt output2.txt >compare.html
-gives you a html file comparing two runs.
-
-*** To run libMicro testsuite with stepper disabled ***
-*** For Desktop use coreos_bench script***
-
-To get a more consistent result of libMicro benchmark run, we need to disable the 
-stepper to prevent it from causing wide variations in results. See rdar://6243819 
-for details.
-
-So to run libMicro test suite with stepper disabled, use 'coreos_bench' script 
-instead of 'bench' script.  
-
-For example:
-./coreos_bench > output.txt
-runs the libMicro test suite excluding the lmbench tests and gives you a text file named output.txt with the results of one run, with stepper disabled.
-Note: 
-1) We need '/usr/local/bin/pstates' to disable the stepper. Install AppleInternal package 
-which provides '/usr/local/bin/pstates'.
-
-2) 'coreos_bench' script is used exactly like the 'bench' script. All the usage examples for 
-'bench' script in this readme file also holds true for 'coreos_bench' script. 
-
-
-
-
-
-*** Makefile ***
-
-The Makefile invokes Makefile.Darwin which invokes Makefile.com.Darwin.
-Just invoke make, with options if necessary, and everything should
-build correctly. The binaries are placed in a directory called
-bin-ARCH where ARCH is the default or specified when building via
-the ARCH flag.
-
-Note:
-1) The binaries of apple added tests are placed in a directory called
-   apple/bin-ARCH
-
-2) All the binaries under bin-ARCH and apple/bin-ARCH are code signed
-   during build.
-options for invoking Makefile are:
-ARCH           defaults to  i386
-
-        to build fat/multi architecture, specify 
-               make ARCH=fat
-       the makefile will automatically build with ARCH_FLAG="-arch i386 -arch x86_64" and put the results in bin-fat
-
-        to build for ARM architecture,
-        first set an environment variable 'SDKROOT' to point to iPhone internal sdk
-       For example:
-               $export SDKROOT="/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.Internal.sdk/"
-       to build use:
-                make ARCH=ARM_ARCH where ARM_ARCH can be for e.g. armv6, armv7 
-        this will put the results in bin-ARM_ARCH
-
-       to build with only two of the architectures see below
-
-ARCH_FLAG      defaults to -arch $(ARCH)
-       to build fat/multi architecture, specify 
-               make ARCH_FLAG="-arch i386" ARCH=fat
-       this will put the results in bin-fat
-
-OPT_FLAG       defaults to  -g
-       to build optimized, specify make OPT_FLAG=-Os
-
-SEMOP_FLAG     defaults to  -DUSE_SEMOP
-       to eliminate SEMOP usage, specify make SEMOP_FLAG=
-       this is needed on some lower-end systems (e.g. M63)
-
-These can be combined, e.g.
-       make ARCH=i386 SEMOP_FLAG=
-
-*** Before running benchmarks ***
-
-The shell script create_stuff should be run before any benchmarking
-
-this script takes care of raising the process limits which would
-otherwise cause several of the tests to fail - if not you will see:
-       Running:           pipe_pst1
-       fork: Resource temporarily unavailable
-in your stderr during the runs. After you run create_stuff, the
-system then needs to be rebooted.
-
-*** running the benchmarks ***
-
-The shell script "bench" will run all the benchmarks, or you can
-pass it a parameter to run a single benchmark, e.g.
-
-*** To run libMicro on the embedded platform, use "embd_bench" script. 'embd_bench' script is used exactly like the 'bench' script. All the usage examples for 
-'bench' script in this readme file also holds true for 'embd_bench' script. ***
-
-       bench lmbench_bw_unix
-
-By default the script will run only the libMicro testsuite excluding the lmbench tests. 
-To run the libmicro testsuite with the lmbench tests included, just pass the -l parameter. e.g,
-       
-       bench -l 
-To run only the lmbench testsuite 
-
-       bench lmbench
-
-To display the usage, just do
-       bench -h
-
-Watch for:
-       # WARNINGS
-       #     Quantization error likely;increase batch size (-B option) 4X to avoid.
-in the output
-To see an example run the supplied testbench script
-
-Add or adjust the -B parameter for any benchmark that fails. The
-Quantization error will refer to the benchmark preceding the error,
-not the one following...
-
-A typical run:
-       $ make clean
-       $ make
-       $ ./create_stuff
-       $ ./bench > output1
-       Running:              getpid
-        for      0.13353 seconds
-       Running:             getppid
-        for      3.65609 seconds
-       Running:              getenv
-        for      0.20924 seconds
-       Running:            getenvT2
-        for      0.37437 seconds
-       Running:        gettimeofday
-        for      0.58077 seconds
-       etc...
-
-Use the supplied multiview script to compare runs like:
-
-multiview output1 output2 > compare.html
-open compare.html (safari launches)
-will show output2 results as a percentage change from the output1 results
-
-*** Adding additional benchmark tests ***
-
-Look at the sample file trivial.c.  This demonstrates how to do
-argument passing, the flow of control of a benchmark, etc. for the
-trivial case.  The tests starting with "lmbench_" were ported from
-the lmbench suite, so they might be good examples as well.
-
-*** A note regarding future changes in bench.sh script ***
-coreos_bench.sh script is almost identical to bench.sh script, except that it
-has additional code to disable the stepper during libmicro benchmark run. 
-
-In future, if bench.sh script is modified, make sure the changes reflect
-in coreos_bench.sh script also.
-
-*** Things to do ***
-
-* port the rest of the lmbench benchmarks into this framework
-
-* create website that will allow easy ability to compare many builds
-across many machines with historical repository of runs
-
-* document better how to write a benchmark for this framework
-(started in trivial.c)
-
-* check this into xnu/test
-
-* create new benchmarks
-
-*** Leopard notes ***
-
-Due to rdar://4654956 and its original, rdar://2588252 you cannot
-run these tests on Leopard without removing the cascade_lockf test.
-There may be other tests which panic a Leopard system.
-
-*** benchDS notes ***
-
-From rdar://problem/7468995 add the ability to benchmark the key APIs
-for server daemons.  In particular, a test binary is added for each of:
-
-       ODQueryCreateWithNode()  (standard User, Groups, and Hosts records)
-       getaddrinfo()  (hosts and ports)
-       mbr_check_service_membership()
-       mbr_check_membership()
-       getpwnam()
-       getpwuid()
-       getgrgid()
-       getpwent()
-       getgrent()
-       getgrnam()
-
-The script benchDS is provided to run a standard set of tests presuming
-that the tests are run by root on a system configured with an OD binding.
-The OD server (local or remote) must have a set of accounts created with
-od_acount_create shell script.  This script must also be run as root, 
-and passed a single argument of the number of users to create.  It creates
-od_test_{1..N}, and all belong to a ds_test_group1(gid 1211).  In addition,
-ds_test_group2(gid 1212) is created which has no users as members.  User ids are
-set sequentially from 5000.  In order to administer the OD server, it assumes
-user 'diradmin' and password 'admin' are the OD admin.
-
-Also, these tests consult the APIs listed, which can be run against the local
-account info, or even Active Directory.
-
-Thus, the quick recipe is:
-       Install X Server
-       Enable OD, and create directory admin user 'diradmin' with password 'admin'
-       As root run:  od_account_create 1000
-       Now run the test, as root:  ./benchDS 1000 > output-file
-
-
-In addition, od_account_delete 1000 will delete the 1000 users created with od_account_create.
-
-
diff --git a/tools/tests/libMicro/Makefile b/tools/tests/libMicro/Makefile
deleted file mode 100644 (file)
index 3eecede..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-include Makefile.benchmarks
-
-ARCH = i386
-
-BINS=          $(ALL:%=bin-$(ARCH)/%) bin-$(ARCH)/tattle
-
-# TARBALL_CONTENTS =   \
-       Makefile.benchmarks \
-       Makefile.SunOS  \
-       Makefile.Linux  \
-       Makefile.Aix    \
-       Makefile.com    \
-       Makefile        \
-       $(ALL:%=%.c)    \
-       elided.c        \
-       exec_bin.c      \
-       libmicro.c      \
-       libmicro_main.c \
-       libmicro.h      \
-       recurse2.c      \
-       benchmark_finibatch.c   \
-       benchmark_initbatch.c   \
-       benchmark_optswitch.c   \
-       benchmark_fini.c        \
-       benchmark_init.c        \
-       benchmark_result.c      \
-       benchmark_finirun.c     \
-       benchmark_initrun.c     \
-       benchmark_initworker.c  \
-       benchmark_finiworker.c  \
-       bench           \
-       bench.sh        \
-       coreos_bench    \
-       coreos_bench.sh \
-       mk_tarball      \
-       multiview       \
-       multiview.sh    \
-       OPENSOLARIS.LICENSE     \
-       tattle.c        \
-       wrapper         \
-       wrapper.sh      \
-       README
-
-ifeq "$(Embedded)" "YES"
-SEMOP_FLAG=
-endif
-
-default $(ALL) run cstyle lint tattle: $(BINS)
-       @cp bench.sh bench
-       @cp coreos_bench.sh coreos_bench
-       @cp embd_bench.sh embd_bench
-       @cp multiview.sh multiview
-       @cp wrapper.sh wrapper
-       @cp create_stuff.sh create_stuff
-       @cp benchDS.sh benchDS
-       @cp od_account_create.sh od_account_create
-       @cp od_account_delete.sh od_account_delete
-       @chmod +x bench coreos_bench embd_bench create_stuff multiview wrapper benchDS od_account_create od_account_delete
-       @mkdir -p bin-$(ARCH); cd bin-$(ARCH); MACH=$(ARCH) $(MAKE) -f ../Makefile.`uname -s` ARCH=$(ARCH) UNAME_RELEASE=`uname -r | sed 's/\./_/g'` $@
-       @echo "code signing all the binaries under bin-$(ARCH) and apple/bin-$(ARCH)"
-       @for file in $(abspath bin-$(ARCH)/*) $(abspath apple/bin-$(ARCH)/*);do        \
-               if test -x $$file;then  \
-                       codesign -s - $$file 1>& /dev/null ;    \
-               fi;     \
-       done;
-       @echo "done"
-
-.PHONY: clean clean_subdirs clean_$(SUBDIRS)
-
-clean: clean_subdirs
-       rm -rf bin bin-* wrapper multiview create_stuff bench tattle benchDS od_account_create od_account_delete coreos_bench embd_bench
-
-clean_subdirs:
-       for dir in $(SUBDIRS); do $(MAKE) -C $$dir clean; done
-
-bin:
-       @mkdir -p bin-$(ARCH)
-
-$(BINS): bin
-       @cp wrapper.sh wrapper
-       @chmod +x wrapper
-       @ln -sf ../wrapper $@
-
-# commenting the lbMicro.tar as it is not being used.
-# libMicro.tar:        FORCE
-#      @chmod +x ./mk_tarball wrapper
-#      @./mk_tarball $(TARBALL_CONTENTS)
-
-# FORCE:
diff --git a/tools/tests/libMicro/Makefile.Aix b/tools/tests/libMicro/Makefile.Aix
deleted file mode 100644 (file)
index 9e4dc42..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-CFLAGS=                -O3
-
-CPPFLAGS = -D_REENTRANT
-
-include ../Makefile.com
-
-NSLLIB=                -lnsl
-SOCKLIB=
-
-.KEEP_STATE:
diff --git a/tools/tests/libMicro/Makefile.Darwin b/tools/tests/libMicro/Makefile.Darwin
deleted file mode 100644 (file)
index 5bb7da2..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# ident        "@(#)Makefile.Darwin    1.5     05/08/04 SMI"
-#
-
-SDKROOT ?= /
-Product=$(shell tconf --product)
-Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
-
-ifeq "$(Embedded)" "YES"
-SDKPATH = $(shell xcodebuild -sdk $(SDKROOT) -version Path)
-CFLAGS += -isysroot $(SDKPATH)
-endif
-
-CC = $(shell xcrun -sdk "$(SDKROOT)" -find gcc)
-#NOPIC=        -mdynamic-no-pic
-ARCH=  i386
-
-ifeq "$(strip $(ARCH))" "fat"
-ARCH_FLAG=      -arch i386 -arch x86_64 
-else
-ARCH_FLAG=     -arch $(ARCH)
-endif
-
-### OPT_FLAG value was modified from '-g' to '-Os' as part of the fix for radar 7508837 
-OPT_FLAG=      -Os
-SEMOP_FLAG=    -DUSE_SEMOP
-
-ifeq "$(Embedded)" "YES"
-SEMOP_FLAG= 
-endif
-
-###
-###CFLAGS=             -Os -DUSE_SEMOP -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-###extra_CFLAGS=       -Os -DUSE_SEMOP -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-###
-CFLAGS+=               $(OPT_FLAG) $(SEMOP_FLAG) -DUSE_GETHRTIME -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-
-ifeq "$(Embedded)" "YES"
-#CFLAGS+=               $(OPT_FLAG) -DUSE_GETHRTIME -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-CFLAGS+= -g -I $(SDKPATH)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/ -F/AppleInternal/Library/Frameworks/ $(MORECFLAGS)
-endif
-
-
-
-extra_CFLAGS=  $(OPT_FLAG) $(SEMOP_FLAG) -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-CPPFLAGS=              $(SEMOP_FLAG) -D_REENTRANT -Wall
-MATHLIB=       -lm
-
-ELIDED_BENCHMARKS=     \
-       cachetocache    \
-       atomic  \
-       getcontext      \
-       setcontext      \
-
-
-include ../Makefile.com.Darwin
diff --git a/tools/tests/libMicro/Makefile.Linux b/tools/tests/libMicro/Makefile.Linux
deleted file mode 100644 (file)
index ca12d15..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-CC=            gcc
-
-#CFLAGS=               -O -DUSE_SEMOP
-CPPFLAGS=              -DUSE_SEMOP -D_REENTRANT
-MATHLIB=       -lm
-
-ELIDED_BENCHMARKS=     \
-       cachetocache    \
-       atomic
-
-
-include ../Makefile.com
diff --git a/tools/tests/libMicro/Makefile.SunOS b/tools/tests/libMicro/Makefile.SunOS
deleted file mode 100644 (file)
index 4fc7269..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-CPPFLAGS=              -DUSE_GETHRTIME -D_REENTRANT
-
-CFLAGS = -O $(extra_CFLAGS)
-
-#
-# These defines allow libmicro to be compiled against older Solaris
-# releases by turning off the tests which don't work there.
-#
-# This is a little contorted-- UNAME_RELEASE is set as an environment
-# variable for us by the invoking make process (see Makefile)-- it is
-# the output of uname -r | sed 's/\./_/g'.
-#
-# We couldn't find any other gmake/unix make portable way to make this
-# work.
-#
-ELIDED_BENCHMARKS_5_8=atomic cachetocache
-ELIDED_BENCHMARKS_5_9=atomic
-
-ELIDED_BENCHMARKS_CMN=cascade_flock
-
-ELIDED_BENCHMARKS=$(ELIDED_BENCHMARKS_CMN) $(ELIDED_BENCHMARKS_$(UNAME_RELEASE))
-
-include ../Makefile.com
-
-NSLLIB=                -lnsl
-SOCKLIB=       -lsocket
-UCBLIB=                -lc -L/usr/ucblib -lucb -R/usr/ucblib
-MATHLIB=       -lm
-
-.KEEP_STATE:
diff --git a/tools/tests/libMicro/Makefile.benchmarks b/tools/tests/libMicro/Makefile.benchmarks
deleted file mode 100644 (file)
index 96c105f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-SUBDIRS = apple
-
-ALL=                           \
-               atomic          \
-               bind            \
-               cachetocache    \
-               cascade_mutex   \
-               cascade_cond    \
-               cascade_lockf   \
-               cascade_fcntl   \
-               cascade_flock   \
-               chdir           \
-               close           \
-               close_tcp       \
-               connection      \
-               dup             \
-               exec            \
-               exit            \
-               exp             \
-               fcntl           \
-               fcntl_ndelay    \
-               file_lock       \
-               fork            \
-               getcontext      \
-               getenv          \
-               gettimeofday    \
-               getpeername     \
-               getpid          \
-               getrusage       \
-               getsockname     \
-               isatty          \
-               listen          \
-               localtime_r     \
-               log             \
-               longjmp         \
-               lrand48         \
-               lseek           \
-               malloc          \
-               memcpy          \
-               memmove         \
-               memrand         \
-               memset          \
-               mktime          \
-               mprotect        \
-               mmap            \
-               msync           \
-               munmap          \
-               mutex           \
-               nop             \
-               open            \
-               pipe            \
-               poll            \
-               pread           \
-               pthread_create  \
-               pwrite          \
-               read            \
-               realpath        \
-               recurse         \
-               select          \
-               semop           \
-               setcontext      \
-               setsockopt      \
-               sigaction       \
-               siglongjmp      \
-               signal          \
-               sigprocmask     \
-               socket          \
-               socketpair      \
-               stat            \
-               strcasecmp      \
-               strchr          \
-               strcmp          \
-               strcpy          \
-               strftime        \
-               strlen          \
-               strtol          \
-               system          \
-               time            \
-               times           \
-               write           \
-               writev
-
-ALL_APPLE =                    \
-               create_file     \
-               getppid                 \
-               lb_mmtest               \
-               lm_null_call            \
-               lmbench_bw_file_rd      \
-               lmbench_bw_mem          \
-               lmbench_bw_mmap_rd      \
-               lmbench_bw_unix         \
-               lmbench_fstat           \
-               lmbench_lat_sig_catch   \
-               lmbench_lat_sig_install \
-               lmbench_lat_sig_prot    \
-               lmbench_lat_sig_send    \
-               lmbench_openclose       \
-               lmbench_read            \
-               lmbench_select_file     \
-               lmbench_select_tcp      \
-               lmbench_stat            \
-               lmbench_write           \
-               posix_spawn             \
-               trivial                 \
-               vm_allocate
-
-
diff --git a/tools/tests/libMicro/Makefile.com b/tools/tests/libMicro/Makefile.com
deleted file mode 100644 (file)
index 5cb92a1..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.benchmarks
-
-EXTRA_CFILES= \
-               exec_bin.c      \
-               elided.c        \
-               tattle.c
-
-#
-# some definitions to make getting compiler versions possible - avoid quotes
-#
-COMPILER_VERSION_CMD_cc=cc -V 2>&1 | egrep Sun
-COMPILER_VERSION_CMD_gcc=gcc -dumpversion
-COMPILER_VERSION_CMD=$(COMPILER_VERSION_CMD_$(CC))
-
-default: $(ALL) tattle
-
-cstyle:        
-       for file in $(ALL:%=../%.c) $(EXTRA_CFILES:%=../%) ; \
-       do cstyle -p $$file ;\
-       done
-
-
-lint:  libmicro.ln $(ALL:%=%.lint) $(EXTRA_CFILES:%.c=%.lint)
-
-
-$(EXTRA_CFILES:%.c=%.lint):
-       $(LINT) ../$(@:%.lint=%.c) -I. -mu -lc libmicro.ln -lm
-
-%.lint:        ../%.c libmicro.ln
-       $(LINT) -mu $(CPPFLAGS) $< libmicro.ln -lpthread -lsocket -lnsl -lm
-
-%.o:   ../%.c
-       $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
-
-libmicro.ln: ../libmicro.c ../libmicro_main.c ../libmicro.h ../benchmark_*.c
-       $(LINT) -muc $(CPPFLAGS) ../libmicro.c ../libmicro_main.c ../benchmark_*.c
-
-CPPFLAGS+= -D_REENTRANT
-
-bind_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-cascade_flock_EXTRA_LIBS=$(UCBLIB)
-close_tcp_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-connection_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-fcntl_ndelay_EXTRA_LIBS=$(SOCKLIB)
-getpeername_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-getsockname_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-listen_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-log_EXTRA_LIBS=$(MATHLIB)
-pipe_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-poll_EXTRA_LIBS=$(SOCKLIB)
-select_EXTRA_LIBS=$(SOCKLIB)
-setsockopt_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-socket_EXTRA_LIBS=$(SOCKLIB)
-socketpair_EXTRA_LIBS=$(SOCKLIB)
-
-BENCHMARK_FUNCS=               \
-       benchmark_init.o        \
-       benchmark_fini.o        \
-       benchmark_initrun.o     \
-       benchmark_finirun.o     \
-       benchmark_initbatch.o   \
-       benchmark_finibatch.o   \
-       benchmark_initworker.o  \
-       benchmark_finiworker.o  \
-       benchmark_optswitch.o   \
-       benchmark_result.o
-
-recurse_EXTRA_DEPS=recurse2.o
-
-
-recurse:       $(recurse_EXTRA_DEPS)
-
-libmicro.a:    libmicro.o libmicro_main.o $(BENCHMARK_FUNCS)
-               $(AR) -cr libmicro.a libmicro.o libmicro_main.o $(BENCHMARK_FUNCS)
-
-tattle:                ../tattle.c     libmicro.a
-       echo "char * compiler_version = \""`$(COMPILER_VERSION_CMD)`"\";" > tattle.h
-       echo "char * CC = \""$(CC)"\";" >> tattle.h
-       echo "char * extra_compiler_flags = \""$(extra_CFLAGS)"\";" >> tattle.h
-       $(CC) -o tattle $(CFLAGS) -I. ../tattle.c libmicro.a -lrt -lm
-       cp tattle ../tattle
-
-$(ELIDED_BENCHMARKS):  ../elided.c
-       $(CC) -o $(@) ../elided.c
-
-%: libmicro.a %.o 
-       $(CC) -o $(@) $(@).o $($(@)_EXTRA_DEPS) $(CFLAGS) libmicro.a $($(@)_EXTRA_LIBS) $(EXTRA_LIBS) -lpthread -lm
-
-exec:  exec_bin
-
-exec_bin:      exec_bin.o
-       $(CC) -o exec_bin $(CFLAGS) exec_bin.o
-
-FORCE:
-
-
-._KEEP_STATE:
-
diff --git a/tools/tests/libMicro/Makefile.com.Darwin b/tools/tests/libMicro/Makefile.com.Darwin
deleted file mode 100644 (file)
index eb942db..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# ident        "@(#)Makefile.com.Darwin        1.10    05/08/04 SMI"
-#
-
-include ../Makefile.benchmarks
-
-EXTRA_CFILES= \
-               exec_bin.c      \
-               elided.c        \
-               tattle.c
-
-#
-# some definitions to make getting compiler versions possible - avoid quotes
-#
-COMPILER_VERSION_CMD_cc=cc -V 2>&1 | egrep Sun
-COMPILER_VERSION_CMD_gcc=gcc -dumpversion
-COMPILER_VERSION_CMD=$(COMPILER_VERSION_CMD_$(CC))
-
-default: $(ALL) subdirs tattle
-
-cstyle:        
-       for file in $(ALL:%=../%.c) $(EXTRA_CFILES:%=../%) ; \
-       do cstyle -p $$file ;\
-       done
-
-
-lint:  libmicro.ln $(ALL:%=%.lint) $(EXTRA_CFILES:%.c=%.lint)
-
-
-$(EXTRA_CFILES:%.c=%.lint):
-       $(LINT) ../$(@:%.lint=%.c) -I. -mu -lc libmicro.ln -lm
-
-%.lint:        ../%.c libmicro.ln
-       $(LINT) -mu $(CPPFLAGS) $< libmicro.ln -lpthread -lsocket -lnsl -lm
-
-%.o:   ../%.c
-       $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
-
-libmicro.ln: ../libmicro.c ../libmicro_main.c ../libmicro.h ../benchmark_*.c
-       $(LINT) -muc $(CPPFLAGS) ../libmicro.c ../libmicro_main.c ../benchmark_*.c
-
-CPPFLAGS+= -D_REENTRANT
-
-bind_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-cascade_flock_EXTRA_LIBS=$(UCBLIB)
-close_tcp_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-connection_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-fcntl_ndelay_EXTRA_LIBS=$(SOCKLIB)
-getpeername_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-getsockname_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-listen_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-log_EXTRA_LIBS=$(MATHLIB)
-pipe_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-poll_EXTRA_LIBS=$(SOCKLIB)
-select_EXTRA_LIBS=$(SOCKLIB)
-setsockopt_EXTRA_LIBS=$(NSLLIB) $(SOCKLIB)
-socket_EXTRA_LIBS=$(SOCKLIB)
-socketpair_EXTRA_LIBS=$(SOCKLIB)
-
-BENCHMARK_FUNCS=               \
-       benchmark_init.o        \
-       benchmark_fini.o        \
-       benchmark_initrun.o     \
-       benchmark_finirun.o     \
-       benchmark_initbatch.o   \
-       benchmark_finibatch.o   \
-       benchmark_initworker.o  \
-       benchmark_finiworker.o  \
-       benchmark_optswitch.o   \
-       benchmark_result.o
-
-recurse_EXTRA_DEPS=recurse2.o
-
-
-recurse:       $(recurse_EXTRA_DEPS)
-
-libmicro.a:    libmicro.o libmicro_main.o $(BENCHMARK_FUNCS)
-               $(AR) -cr libmicro.a libmicro.o libmicro_main.o $(BENCHMARK_FUNCS)
-               ranlib libmicro.a
-
-tattle:                ../tattle.c     libmicro.a
-       echo "char * compiler_version = \""`$(COMPILER_VERSION_CMD)`"\";" > tattle.h
-       echo "char * CC = \""$(CC)"\";" >> tattle.h
-       echo "char * extra_compiler_flags = \""$(extra_CFLAGS)"\";" >> tattle.h
-       $(CC) -o tattle $(CFLAGS) -I. ../tattle.c libmicro.a -lSystem -lm
-       cp tattle ../tattle
-
-$(ELIDED_BENCHMARKS):  ../elided.c
-       $(CC) $(CFLAGS) -o $(@) ../elided.c
-
-%: libmicro.a %.o 
-       $(CC) -o $(@) $(@).o $($(@)_EXTRA_DEPS) $(CFLAGS) libmicro.a $($(@)_EXTRA_LIBS) $(EXTRA_LIBS) -lpthread -lm
-
-exec:  exec_bin
-
-exec_bin:      exec_bin.o
-       $(CC) -o exec_bin $(CFLAGS) exec_bin.o
-
-# for apple added tests
-
-.PHONY: subdirs $(SUBDIRS)
-
-subdirs: $(SUBDIRS)
-
-$(SUBDIRS): 
-       cd ..; $(MAKE) -C $@ ARCH=$(ARCH)
-
-
-
-FORCE:
-
-
-._KEEP_STATE:
-
diff --git a/tools/tests/libMicro/OPENSOLARIS.LICENSE b/tools/tests/libMicro/OPENSOLARIS.LICENSE
deleted file mode 100644 (file)
index 535dec2..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-Unless otherwise noted, all files in this distribution are released
-under the Common Development and Distribution License (CDDL),
-Version 1.0 only.  Exceptions are noted within the associated
-source files.
-
---------------------------------------------------------------------
-
-
-COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
-
-1. Definitions.
-
-    1.1. "Contributor" means each individual or entity that creates
-         or contributes to the creation of Modifications.
-
-    1.2. "Contributor Version" means the combination of the Original
-         Software, prior Modifications used by a Contributor (if any),
-         and the Modifications made by that particular Contributor.
-
-    1.3. "Covered Software" means (a) the Original Software, or (b)
-         Modifications, or (c) the combination of files containing
-         Original Software with files containing Modifications, in
-         each case including portions thereof.
-
-    1.4. "Executable" means the Covered Software in any form other
-         than Source Code.
-
-    1.5. "Initial Developer" means the individual or entity that first
-         makes Original Software available under this License.
-
-    1.6. "Larger Work" means a work which combines Covered Software or
-         portions thereof with code not governed by the terms of this
-         License.
-
-    1.7. "License" means this document.
-
-    1.8. "Licensable" means having the right to grant, to the maximum
-         extent possible, whether at the time of the initial grant or
-         subsequently acquired, any and all of the rights conveyed
-         herein.
-
-    1.9. "Modifications" means the Source Code and Executable form of
-         any of the following:
-
-        A. Any file that results from an addition to, deletion from or
-           modification of the contents of a file containing Original
-           Software or previous Modifications;
-
-        B. Any new file that contains any part of the Original
-           Software or previous Modifications; or
-
-        C. Any new file that is contributed or otherwise made
-           available under the terms of this License.
-
-    1.10. "Original Software" means the Source Code and Executable
-          form of computer software code that is originally released
-          under this License.
-
-    1.11. "Patent Claims" means any patent claim(s), now owned or
-          hereafter acquired, including without limitation, method,
-          process, and apparatus claims, in any patent Licensable by
-          grantor.
-
-    1.12. "Source Code" means (a) the common form of computer software
-          code in which modifications are made and (b) associated
-          documentation included in or with such code.
-
-    1.13. "You" (or "Your") means an individual or a legal entity
-          exercising rights under, and complying with all of the terms
-          of, this License.  For legal entities, "You" includes any
-          entity which controls, is controlled by, or is under common
-          control with You.  For purposes of this definition,
-          "control" means (a) the power, direct or indirect, to cause
-          the direction or management of such entity, whether by
-          contract or otherwise, or (b) ownership of more than fifty
-          percent (50%) of the outstanding shares or beneficial
-          ownership of such entity.
-
-2. License Grants.
-
-    2.1. The Initial Developer Grant.
-
-    Conditioned upon Your compliance with Section 3.1 below and
-    subject to third party intellectual property claims, the Initial
-    Developer hereby grants You a world-wide, royalty-free,
-    non-exclusive license:
-
-        (a) under intellectual property rights (other than patent or
-            trademark) Licensable by Initial Developer, to use,
-            reproduce, modify, display, perform, sublicense and
-            distribute the Original Software (or portions thereof),
-            with or without Modifications, and/or as part of a Larger
-            Work; and
-
-        (b) under Patent Claims infringed by the making, using or
-            selling of Original Software, to make, have made, use,
-            practice, sell, and offer for sale, and/or otherwise
-            dispose of the Original Software (or portions thereof).
-
-        (c) The licenses granted in Sections 2.1(a) and (b) are
-            effective on the date Initial Developer first distributes
-            or otherwise makes the Original Software available to a
-            third party under the terms of this License.
-
-        (d) Notwithstanding Section 2.1(b) above, no patent license is
-            granted: (1) for code that You delete from the Original
-            Software, or (2) for infringements caused by: (i) the
-            modification of the Original Software, or (ii) the
-            combination of the Original Software with other software
-            or devices.
-
-    2.2. Contributor Grant.
-
-    Conditioned upon Your compliance with Section 3.1 below and
-    subject to third party intellectual property claims, each
-    Contributor hereby grants You a world-wide, royalty-free,
-    non-exclusive license:
-
-        (a) under intellectual property rights (other than patent or
-            trademark) Licensable by Contributor to use, reproduce,
-            modify, display, perform, sublicense and distribute the
-            Modifications created by such Contributor (or portions
-            thereof), either on an unmodified basis, with other
-            Modifications, as Covered Software and/or as part of a
-            Larger Work; and
-
-        (b) under Patent Claims infringed by the making, using, or
-            selling of Modifications made by that Contributor either
-            alone and/or in combination with its Contributor Version
-            (or portions of such combination), to make, use, sell,
-            offer for sale, have made, and/or otherwise dispose of:
-            (1) Modifications made by that Contributor (or portions
-            thereof); and (2) the combination of Modifications made by
-            that Contributor with its Contributor Version (or portions
-            of such combination).
-
-        (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
-            effective on the date Contributor first distributes or
-            otherwise makes the Modifications available to a third
-            party.
-
-        (d) Notwithstanding Section 2.2(b) above, no patent license is
-            granted: (1) for any code that Contributor has deleted
-            from the Contributor Version; (2) for infringements caused
-            by: (i) third party modifications of Contributor Version,
-            or (ii) the combination of Modifications made by that
-            Contributor with other software (except as part of the
-            Contributor Version) or other devices; or (3) under Patent
-            Claims infringed by Covered Software in the absence of
-            Modifications made by that Contributor.
-
-3. Distribution Obligations.
-
-    3.1. Availability of Source Code.
-
-    Any Covered Software that You distribute or otherwise make
-    available in Executable form must also be made available in Source
-    Code form and that Source Code form must be distributed only under
-    the terms of this License.  You must include a copy of this
-    License with every copy of the Source Code form of the Covered
-    Software You distribute or otherwise make available.  You must
-    inform recipients of any such Covered Software in Executable form
-    as to how they can obtain such Covered Software in Source Code
-    form in a reasonable manner on or through a medium customarily
-    used for software exchange.
-
-    3.2. Modifications.
-
-    The Modifications that You create or to which You contribute are
-    governed by the terms of this License.  You represent that You
-    believe Your Modifications are Your original creation(s) and/or
-    You have sufficient rights to grant the rights conveyed by this
-    License.
-
-    3.3. Required Notices.
-
-    You must include a notice in each of Your Modifications that
-    identifies You as the Contributor of the Modification.  You may
-    not remove or alter any copyright, patent or trademark notices
-    contained within the Covered Software, or any notices of licensing
-    or any descriptive text giving attribution to any Contributor or
-    the Initial Developer.
-
-    3.4. Application of Additional Terms.
-
-    You may not offer or impose any terms on any Covered Software in
-    Source Code form that alters or restricts the applicable version
-    of this License or the recipients' rights hereunder.  You may
-    choose to offer, and to charge a fee for, warranty, support,
-    indemnity or liability obligations to one or more recipients of
-    Covered Software.  However, you may do so only on Your own behalf,
-    and not on behalf of the Initial Developer or any Contributor.
-    You must make it absolutely clear that any such warranty, support,
-    indemnity or liability obligation is offered by You alone, and You
-    hereby agree to indemnify the Initial Developer and every
-    Contributor for any liability incurred by the Initial Developer or
-    such Contributor as a result of warranty, support, indemnity or
-    liability terms You offer.
-
-    3.5. Distribution of Executable Versions.
-
-    You may distribute the Executable form of the Covered Software
-    under the terms of this License or under the terms of a license of
-    Your choice, which may contain terms different from this License,
-    provided that You are in compliance with the terms of this License
-    and that the license for the Executable form does not attempt to
-    limit or alter the recipient's rights in the Source Code form from
-    the rights set forth in this License.  If You distribute the
-    Covered Software in Executable form under a different license, You
-    must make it absolutely clear that any terms which differ from
-    this License are offered by You alone, not by the Initial
-    Developer or Contributor.  You hereby agree to indemnify the
-    Initial Developer and every Contributor for any liability incurred
-    by the Initial Developer or such Contributor as a result of any
-    such terms You offer.
-
-    3.6. Larger Works.
-
-    You may create a Larger Work by combining Covered Software with
-    other code not governed by the terms of this License and
-    distribute the Larger Work as a single product.  In such a case,
-    You must make sure the requirements of this License are fulfilled
-    for the Covered Software.
-
-4. Versions of the License.
-
-    4.1. New Versions.
-
-    Sun Microsystems, Inc. is the initial license steward and may
-    publish revised and/or new versions of this License from time to
-    time.  Each version will be given a distinguishing version number.
-    Except as provided in Section 4.3, no one other than the license
-    steward has the right to modify this License.
-
-    4.2. Effect of New Versions.
-
-    You may always continue to use, distribute or otherwise make the
-    Covered Software available under the terms of the version of the
-    License under which You originally received the Covered Software.
-    If the Initial Developer includes a notice in the Original
-    Software prohibiting it from being distributed or otherwise made
-    available under any subsequent version of the License, You must
-    distribute and make the Covered Software available under the terms
-    of the version of the License under which You originally received
-    the Covered Software.  Otherwise, You may also choose to use,
-    distribute or otherwise make the Covered Software available under
-    the terms of any subsequent version of the License published by
-    the license steward.
-
-    4.3. Modified Versions.
-
-    When You are an Initial Developer and You want to create a new
-    license for Your Original Software, You may create and use a
-    modified version of this License if You: (a) rename the license
-    and remove any references to the name of the license steward
-    (except to note that the license differs from this License); and
-    (b) otherwise make it clear that the license contains terms which
-    differ from this License.
-
-5. DISCLAIMER OF WARRANTY.
-
-    COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
-    BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-    INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
-    SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
-    PURPOSE OR NON-INFRINGING.  THE ENTIRE RISK AS TO THE QUALITY AND
-    PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU.  SHOULD ANY
-    COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
-    INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
-    NECESSARY SERVICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF
-    WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.  NO USE OF
-    ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
-    DISCLAIMER.
-
-6. TERMINATION.
-
-    6.1. This License and the rights granted hereunder will terminate
-    automatically if You fail to comply with terms herein and fail to
-    cure such breach within 30 days of becoming aware of the breach.
-    Provisions which, by their nature, must remain in effect beyond
-    the termination of this License shall survive.
-
-    6.2. If You assert a patent infringement claim (excluding
-    declaratory judgment actions) against Initial Developer or a
-    Contributor (the Initial Developer or Contributor against whom You
-    assert such claim is referred to as "Participant") alleging that
-    the Participant Software (meaning the Contributor Version where
-    the Participant is a Contributor or the Original Software where
-    the Participant is the Initial Developer) directly or indirectly
-    infringes any patent, then any and all rights granted directly or
-    indirectly to You by such Participant, the Initial Developer (if
-    the Initial Developer is not the Participant) and all Contributors
-    under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
-    notice from Participant terminate prospectively and automatically
-    at the expiration of such 60 day notice period, unless if within
-    such 60 day period You withdraw Your claim with respect to the
-    Participant Software against such Participant either unilaterally
-    or pursuant to a written agreement with Participant.
-
-    6.3. In the event of termination under Sections 6.1 or 6.2 above,
-    all end user licenses that have been validly granted by You or any
-    distributor hereunder prior to termination (excluding licenses
-    granted to You by any distributor) shall survive termination.
-
-7. LIMITATION OF LIABILITY.
-
-    UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
-    (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
-    INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
-    COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
-    LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
-    CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
-    LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
-    STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
-    COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
-    INFORMED OF THE POSSIBILITY OF SUCH DAMAGES.  THIS LIMITATION OF
-    LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
-    INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
-    APPLICABLE LAW PROHIBITS SUCH LIMITATION.  SOME JURISDICTIONS DO
-    NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
-    CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
-    APPLY TO YOU.
-
-8. U.S. GOVERNMENT END USERS.
-
-    The Covered Software is a "commercial item," as that term is
-    defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
-    computer software" (as that term is defined at 48
-    C.F.R. 252.227-7014(a)(1)) and "commercial computer software
-    documentation" as such terms are used in 48 C.F.R. 12.212
-    (Sept. 1995).  Consistent with 48 C.F.R. 12.212 and 48
-    C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
-    U.S. Government End Users acquire Covered Software with only those
-    rights set forth herein.  This U.S. Government Rights clause is in
-    lieu of, and supersedes, any other FAR, DFAR, or other clause or
-    provision that addresses Government rights in computer software
-    under this License.
-
-9. MISCELLANEOUS.
-
-    This License represents the complete agreement concerning subject
-    matter hereof.  If any provision of this License is held to be
-    unenforceable, such provision shall be reformed only to the extent
-    necessary to make it enforceable.  This License shall be governed
-    by the law of the jurisdiction specified in a notice contained
-    within the Original Software (except to the extent applicable law,
-    if any, provides otherwise), excluding such jurisdiction's
-    conflict-of-law provisions.  Any litigation relating to this
-    License shall be subject to the jurisdiction of the courts located
-    in the jurisdiction and venue specified in a notice contained
-    within the Original Software, with the losing party responsible
-    for costs, including, without limitation, court costs and
-    reasonable attorneys' fees and expenses.  The application of the
-    United Nations Convention on Contracts for the International Sale
-    of Goods is expressly excluded.  Any law or regulation which
-    provides that the language of a contract shall be construed
-    against the drafter shall not apply to this License.  You agree
-    that You alone are responsible for compliance with the United
-    States export administration regulations (and the export control
-    laws and regulation of any other countries) when You use,
-    distribute or otherwise make available any Covered Software.
-
-10. RESPONSIBILITY FOR CLAIMS.
-
-    As between Initial Developer and the Contributors, each party is
-    responsible for claims and damages arising, directly or
-    indirectly, out of its utilization of rights under this License
-    and You agree to work with Initial Developer and Contributors to
-    distribute such responsibility on an equitable basis.  Nothing
-    herein is intended or shall be deemed to constitute any admission
-    of liability.
-
---------------------------------------------------------------------
-
-NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
-DISTRIBUTION LICENSE (CDDL)
-
-For Covered Software in this distribution, this License shall
-be governed by the laws of the State of California (excluding
-conflict-of-law provisions).
-
-Any litigation relating to this License shall be subject to the
-jurisdiction of the Federal Courts of the Northern District of
-California and the state courts of the State of California, with
-venue lying in Santa Clara County, California.
diff --git a/tools/tests/libMicro/README b/tools/tests/libMicro/README
deleted file mode 100644 (file)
index 9db9f81..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-Building the tarball
---------------------
-As long as cc is in your path, (gcc on Linux),
-
-% tar xf libMicro.tar
-% make
-
-will build the benchmark suite.
-
-Running the benchmarks
------------------------
-
-A set of generic scripts to invoke each micro benchmark
-are created in the bin directory; these may be invoked
-directly.  Note that the actual binaries are created in
-OS-specific directories; this allows one to build for
-all varients (x86/sparc/Solaris/Linux) in one place.
-
-To collect a complete set of benchmarks, use the bench
-script and redirect its output to a file.
-
-% ./bench > output
-
-To compare the output of two or more runs, use multiview in the src
-directory:
-
-% ./multiview reference compare1 compare2 compare2 > compare.html
-%
-
-where the reference and compare files contain the output of different
-libmicro runs.
-
-The compare.html file will allow quick comparisons to be drawn,
-allowing a variety of experiments to be quickly analyzed.
-
-All benchmarks support the following options:
-
-       [-1] (single process; overrides -P > 1)
-       [-A] (align with clock)
-       [-B batch-size (default 10)]
-       [-C minimum number of samples (default 0)]
-       [-D duration in msecs (default 10s)]
-       [-E (echo name to stderr)]
-       [-H] (suppress headers)
-       [-I] specify approx. time per op in nsecs
-       [-L] (print argument line)
-       [-M] (reports mean rather than median)
-       [-N test-name ]
-       [-P processes (default 1)]
-       [-S] (print detailed stats)
-       [-T threads (default 1)]
-       [-V] (print the libMicro version and exit)
-       [-W] (flag possible benchmark problems)
-
-
-Apple-added Benchmarks
------------------------
-
-       create_file
-       geekbench_stdlib_write
-       getaddrinfo_port
-       getaddrinfo_host
-       getgrgid
-       getgrent
-       getgrnam
-       getppid
-       getpwnam
-       getpwuid
-       getpwent
-       lb_mmtest
-       lm_null_call
-       lmbench_bw_file_rd
-       lmbench_bw_mem
-       lmbench_bw_mmap_rd
-       lmbench_bw_unix
-       lmbench_fstat
-       lmbench_lat_ctx
-       lmbench_lat_sig_catch
-       lmbench_lat_sig_install
-       lmbench_lat_sig_prot
-       lmbench_lat_sig_send
-       lmbench_openclose
-       lmbench_read
-       lmbench_select_file
-       lmbench_select_tcp
-       lmbench_stat
-       lmbench_write
-       mbr_check_service_membership
-       mbr_check_membership
-       od_query_create_with_node
-       trivial
-       vm_allocate
-
-Also, please read AppleReadMe for further information.
-
diff --git a/tools/tests/libMicro/apple/Makefile b/tools/tests/libMicro/apple/Makefile
deleted file mode 100644 (file)
index 906ef96..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-include Makefile.benchmarks
-
-ARCH=   i386
-
-BINS=  $(ALL:%=../bin-$(ARCH)/%)
-
-default $(ALL): $(BINS)
-       @mkdir -p bin-$(ARCH); cd bin-$(ARCH); MACH=$(ARCH) $(MAKE) -f ../Makefile.`uname -s` ARCH=$(ARCH) UNAME_RELEASE=`uname -r | sed 's/\./_/g'` $@
-
-clean:
-       rm -rf bin bin-*
-
-bin:
-       @mkdir -p ../bin-$(ARCH)
-
-$(BINS): bin
diff --git a/tools/tests/libMicro/apple/Makefile.Darwin b/tools/tests/libMicro/apple/Makefile.Darwin
deleted file mode 100644 (file)
index ff1f4a6..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# ident        "@(#)Makefile.Darwin    1.5     05/08/04 SMI"
-#
-
-SDKROOT ?= /
-Product=$(shell tconf --product)
-Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
-
-ifeq "$(Embedded)" "YES"
-SDKPATH = $(shell xcodebuild -sdk "$(SDKROOT)" -version Path)
-CFLAGS += -isysroot $(SDKPATH)
-EmbeddedOS=yes
-endif
-
-CC = $(shell xcrun -sdk "$(SDKROOT)" -find gcc)
-#NOPIC=        -mdynamic-no-pic
-ARCH= i386
-
-ifeq "$(strip $(ARCH))" "fat"
-ARCH_FLAG=      -arch i386 -arch x86_64
-else
-ARCH_FLAG=      -arch $(ARCH)
-endif
-
-### OPT_FLAG value was modified from '-g' to '-Os' as part of the fix for radar 7508837
-OPT_FLAG=      -Os
-SEMOP_FLAG=    -DUSE_SEMOP
-ifeq "$(Embedded)" "YES"
-SEMOP_FLAG=
-endif
-
-###
-###CFLAGS=             -Os -DUSE_SEMOP -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-###extra_CFLAGS=       -Os -DUSE_SEMOP -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-###
-CFLAGS+=               $(OPT_FLAG) $(SEMOP_FLAG) -DUSE_GETHRTIME -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-
-ifeq "$(Embedded)" "YES"
-#CFLAGS+=               $(OPT_FLAG) -DUSE_GETHRTIME -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-CFLAGS+= -g -I $(SDKPATH)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/ -F/AppleInternal/Library/Frameworks/ $(MORECFLAGS)
-endif
-
-extra_CFLAGS=  $(OPT_FLAG) $(SEMOP_FLAG) -DUSE_GETHRTIME -fno-builtin $(NOPIC) $(ARCH_FLAG) -Wall
-CPPFLAGS=              $(SEMOP_FLAG) -D_REENTRANT -Wall
-MATHLIB=       -lm
-
-ELIDED_BENCHMARKS=     \
-       cachetocache    \
-       atomic  \
-       getcontext      \
-       setcontext      \
-       fork    \
-       exit    \
-       connection
-
-
-include ../Makefile.com.Darwin
diff --git a/tools/tests/libMicro/apple/Makefile.benchmarks b/tools/tests/libMicro/apple/Makefile.benchmarks
deleted file mode 100644 (file)
index 5fd6566..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
-
-ALL =                  \
-               create_file     \
-               geekbench_stdlib_write  \
-               getppid                 \
-               lb_mmtest               \
-               lm_null_call            \
-               lmbench_bw_file_rd      \
-               lmbench_bw_mem          \
-               lmbench_bw_mmap_rd      \
-               lmbench_bw_unix         \
-               lmbench_fstat           \
-               lmbench_lat_ctx         \
-               lmbench_lat_sig_catch   \
-               lmbench_lat_sig_install \
-               lmbench_lat_sig_prot    \
-               lmbench_lat_sig_send    \
-               lmbench_openclose       \
-               lmbench_read            \
-               lmbench_select_file     \
-               lmbench_select_tcp      \
-               lmbench_stat            \
-               lmbench_write           \
-               posix_spawn             \
-               trivial                 \
-               vm_allocate \
-               mbr_check_service_membership  \
-               getpwnam                \
-               mbr_check_membership    \
-               getpwuid                \
-               getgrgid                \
-               getpwent                \
-               getgrent                \
-               getaddrinfo_host        \
-               getaddrinfo_port        \
-               getgrnam
-
-# Compile the following test on desktop platform only
-ifeq "$(Embedded)" "NO"
-ALL += od_query_create_with_node
-endif
diff --git a/tools/tests/libMicro/apple/Makefile.com.Darwin b/tools/tests/libMicro/apple/Makefile.com.Darwin
deleted file mode 100644 (file)
index a72a316..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# ident        "@(#)Makefile.com.Darwin        1.10    05/08/04 SMI"
-#
-
-include ../Makefile.benchmarks
-
-EXTRA_CFILES= \
-               exec_bin.c      \
-               elided.c        \
-               tattle.c
-
-#
-# some definitions to make getting compiler versions possible - avoid quotes
-#
-COMPILER_VERSION_CMD_cc=cc -V 2>&1 | egrep Sun
-COMPILER_VERSION_CMD_gcc=gcc -dumpversion
-COMPILER_VERSION_CMD=$(COMPILER_VERSION_CMD_$(CC))
-
-default: $(ALL)
-
-%.o:   ../%.c
-       $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
-
-%: %.o
-       $(CC) -o $(@) $(@).o $($(@)_EXTRA_DEPS) $(CFLAGS) ../../bin-$(ARCH)/libmicro.a $($(@)_EXTRA_LIBS) $(EXTRA_LIBS) -lpthread -lm; cp $@ ../../bin-$(ARCH)/
-
-posix_spawn:    posix_spawn_bin
-
-posix_spawn_bin:        posix_spawn_bin.o
-       $(CC) -o posix_spawn_bin $(CFLAGS) posix_spawn_bin.o
-
-od_query_create_with_node:  od_query_create_with_node.o
-       $(CC) -o $(@) $(@).o $($(@)_EXTRA_DEPS) $(CFLAGS) ../../bin-$(ARCH)/libmicro.a $($(@)_EXTRA_LIBS) $(EXTRA_LIBS) -lpthread -lm -framework CoreFoundation -framework OpenDirectory; cp $@ ../../bin-$(ARCH)/
diff --git a/tools/tests/libMicro/apple/create_file.c b/tools/tests/libMicro/apple/create_file.c
deleted file mode 100644 (file)
index f4e5abf..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)trivial.c  1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-// add additional headers needed here.
-#include <fcntl.h>
-
-#include "../libmicro.h"
-
-#if DEBUG
-# define debug(fmt, args...)   (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-#define MAXPATHLEN     1024
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-        int     ts_once;
-} tsd_t;
-
-/*
- * You can have any lower-case option you want to define.
- * options are specified in the lm_optstr as either a 
- * single lower-case letter, or a single lower case letter 
- * with a colon after it.  In this example, you can optionally
- * specify -c {str} -e or -t {number}  
- *    -c takes a string (quote the string if blanks)
- *    -e is a boolean 
- *    -t takes a numeric
- * argument.
- */
-static char *  optf; // allocated in benchmark_init, freed in benchmark_fini.
-
-
-int
-benchmark_init()
-{
-       debug("benchmark_init\n");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "f:");
-       /*
-        *      tsd_t is the state info struct that we pass around 
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "               -f filename\n"
-           "notes: measures file creation using open(2)\n");
-       
-       optf = malloc(MAXPATHLEN);
-       sprintf(optf, "/tmp/create_file_%d", getpid());
-       return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- * the format was defined in the lm_optstr assignment
- * in benchmark_init
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       debug("benchmark_optswitch\n");
-       
-       switch (opt) {
-       case 'f':
-               strncpy(optf, optarg, 20);
-               (void)fprintf(stderr, "optf = %s\n", optf);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       debug("benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-//     tsd_t                   *ts = (tsd_t *)tsd;
-//     debug("benchmark_initworker: ts_once = %i\n",ts->ts_once);      
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       // useless code to show what you can do.
-        ts->ts_once++;
-        ts->ts_once--;
-       debug("benchmark_initbatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      try not to initialize things here.  This is the main
-        *  loop of things to get timed.  Start a server in 
-        *  benchmark_initbatch
-        */
-//     tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       
-       debug("in to benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-       for (i = 0; i < lm_optB; i++) {
-                if (!open(optf, O_CREAT))
-                       res->re_errors++;
-       }
-       res->re_count = i;
-       debug("out of benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-//     tsd_t                   *ts = (tsd_t *)tsd;
-//     debug("benchmark_finibatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       // useless code to show what you can do.
-        ts->ts_once++;
-        ts->ts_once--;
-       debug("benchmark_finiworker: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       debug("benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finirun()
-{
-       debug("benchmark_finirun\n");
-       return (0);
-}
-
-
-int
-benchmark_fini()
-{
-       debug("benchmark_fini\n");
-       free(optf);
-       return (0);
-}
-
diff --git a/tools/tests/libMicro/apple/geekbench_stdlib_write.c b/tools/tests/libMicro/apple/geekbench_stdlib_write.c
deleted file mode 100644 (file)
index 65bcee9..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)geekbench_stdlib_write.c   1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-        int     ts_once;
-} tsd_t;
-
-unsigned char * arena;
-unsigned int    arenaSize = 1048576;
-
-static int     optt = 1;
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       //(void) fprintf(stderr, "benchmark_initbatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       (void) fprintf(stderr, "benchmark_finirun\n");
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       (void) fprintf(stderr, "benchmark_init\n");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "t:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-t int (default 1)]\n"
-           "notes: measures nothing\n");
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       (void) fprintf(stderr, "benchmark_fini\n");
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       /* 
-        *      more proof of state passing
-        */
-       ts->ts_once = optt;
-       //(void) fprintf(stderr, "benchmark_finibatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       //(void) fprintf(stderr, "benchmark_finiworker: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       (void) fprintf(stderr, "benchmark_optswitch\n");
-       
-       switch (opt) {
-       case 't':
-               optt = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       //ts->ts_once = optt;
-       //(void) fprintf(stderr, "benchmark_initworker: ts_once = %i\n",ts->ts_once);
-       arena = ( unsigned char * )malloc( arenaSize);
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       //(void) fprintf(stderr, "benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       int                     i;
-       
-       //(void) fprintf(stderr, "in to benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-       for (i = 0; i < lm_optB; i++) {
-               /*
-                *      just to show that ts really contains state
-                */
-                //(void) fprintf(stderr, "i is %i\n",i);
-                memset( arena, 0, arenaSize );
-       }
-       res->re_count = i;
-       //(void) fprintf(stderr, "out of benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/getaddrinfo_host.c b/tools/tests/libMicro/apple/getaddrinfo_host.c
deleted file mode 100644 (file)
index a704175..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-#include <netdb.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-//
-// Correct use case
-//
-//    getaddrinfo_host -E  -L -S -W -B 200 -C 100 -s "server%d"
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -h is hostname format: for example, "server-%d.performance.rack"
-//                        this is C language string format that can include %d
-// -r hostname digit range in the form of "min-max". For example, -r 100-112
-//    With -h and -r, resulting hostnames are
-//      server-100.performance.rack - server-112.performance.rack
-//
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-#define HOSTNAME_LEN    125
-static int host_min=-1, host_range=0;
-static char *hostname_format=NULL;
-static char *hostname_list=NULL;
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "l:h:r:");
-
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n       ------- getaddrinfo_host specific options (default: *)\n"
-                "       [-h \"hostname format\"]. ie. \"server-%%d.perf\"\n"
-                "       [-r min-max]\n"
-                "\n" );
-
-    return (0);
-}
-
-
-int
-parse_range(int *min, int *offset, char *buf)
-{
-    char *value, *tmp_ptr = strdup(buf);
-    int range=0;
-    debug("parse_range");
-
-    value = strsep(&tmp_ptr, "-");
-    *min = atoi(value);
-    debug("min = %d", *min);
-    if (tmp_ptr) {
-        value = strsep(&tmp_ptr, "-");
-        range = atoi(value);
-        if (range < *min) {
-            printf("max id should be larger than min id\n");
-            return -1;
-        }
-        *offset = range - *min + 1; // 1-based
-        debug("range = %d", *offset);
-    }
-    else {
-        printf("argument should be in the form of min-max\n");
-        return -1;
-    }
-
-    return 0;
-
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'h':   // hostname string format
-        hostname_format = strdup(optarg);
-        debug ("hostname format: %s", hostname_format);
-        break;
-
-       case 'l':
-               gL1CacheEnabled = atoi(optarg);
-               break;
-
-    case 'r':    // UID range
-        return parse_range( &host_min, &host_range, optarg);
-        break;
-
-    default:
-        return -1;
-    }
-
-    
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-//
-int
-benchmark_initrun()
-{
-    int i;
-
-    debug("\nbenchmark_initrun");
-
-    if (host_min == -1) {
-        printf("-r min-max needs to be specified\n");
-        exit (1);
-    }
-
-    if (!hostname_format) {
-        printf("-h hostname_format needs to be specified\n");
-        exit (1);
-    }
-
-    hostname_list = malloc ( host_range * HOSTNAME_LEN );
-    if (!hostname_list) {
-        debug("malloc error");
-        exit (1);
-    }
-
-    for (i = 0; i < host_range; i++) {
-        sprintf( &hostname_list[i*HOSTNAME_LEN], hostname_format, i+host_min);
-        // debug("hostname: %s", &hostname_list[i*HOSTNAME_LEN]);
-    }
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i, index, err;
-    struct addrinfo *addi;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    srandom(getpid());
-
-    for (i = 0; i < lm_optB; i++) {
-        index = HOSTNAME_LEN * (random() % host_range);
-
-        err = getaddrinfo( &hostname_list[index], NULL, NULL, &addi);
-
-        if (err) {
-            debug("%s: error: %s", &hostname_list[index], gai_strerror(err));
-            res->re_errors++;
-        }
-        else {
-            debug("host %s done", &hostname_list[index]);
-        }
-
-        freeaddrinfo (addi);
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun ");
-
-    free(hostname_list);
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getaddrinfo_port.c b/tools/tests/libMicro/apple/getaddrinfo_port.c
deleted file mode 100644 (file)
index 846486f..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-#include <netdb.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// This exercises "ssh" port
-//
-// Correct use case
-//
-//    getaddrinfo_port -E  -L -S -W -B 200 -C 100
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-//
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-
-    (void) sprintf(lm_optstr,  "l:");
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    return (0);
-}
-
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-        case 'l':
-            gL1CacheEnabled = atoi(optarg);
-            break;
-    }
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-//
-int
-benchmark_initrun()
-{
-    debug("\nbenchmark_initrun");
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i, err;
-    struct addrinfo *addi;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-
-        err = getaddrinfo(NULL, "ssh", NULL, &addi);
-
-        if (err) {
-            debug("error: %s", gai_strerror(err));
-            res->re_errors++;
-        }
-
-        freeaddrinfo (addi);
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun ");
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getgrent.c b/tools/tests/libMicro/apple/getgrent.c
deleted file mode 100644 (file)
index 321bbed..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <grp.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    getgrent -E  -L -S -W -B 200 -C 100
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-//
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-
-    (void) sprintf(lm_optstr,  "l:");
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    return (0);
-}
-
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-    
-    switch (opt) {
-        case 'l':
-            gL1CacheEnabled = atoi(optarg);
-            break;
-    }
-    
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-//
-int
-benchmark_initrun()
-{
-    debug("\nbenchmark_initrun");
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i;
-    struct group *grp;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-
-        errno = 0;      // this is needed explicitly due to getgrent() design
-        grp = getgrent();
-
-        if (!grp) {
-            if (errno) {
-                debug("error: %s", strerror(errno));
-                res->re_errors++;
-            }
-            else {
-                // will not be counted as error
-                setgroupent(1);  // rewind to the beginning of passwd file
-            }
-        }
-        else {
-            debug("gr_name: %s", grp->gr_name);
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun ");
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getgrgid.c b/tools/tests/libMicro/apple/getgrgid.c
deleted file mode 100644 (file)
index f49925d..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <membership.h>
-#include <grp.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    getgrgid -E  -L -S -W -B 200 -C 10 -g 1211-1213
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -g gid range in the form of "min-max". For example, -g 1211-1213
-//
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-// temporary buffer size
-#define BUFSIZE 200
-#define INVALID_ID  -1
-
-static gid_t  gid_min = INVALID_ID;
-static int    gid_range = 0;  // gid_max = gid_min + gid_range
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "l:g:");
-
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n     ------- getgrgid specific options (default: *)\n"
-                "       [-g GID range (min-max)]\n"
-                "\n" );
-    return (0);
-}
-
-
-int
-parse_range(gid_t *min, int *offset, char *buf)
-{
-    char *value, *tmp_ptr = strdup(buf);
-    int range=0;
-    debug("parse_range");
-
-    value = strsep(&tmp_ptr, "-");
-    *min = atoi(value);
-    debug("min = %d", *min);
-    if (tmp_ptr) {
-        value = strsep(&tmp_ptr, "-");
-        range = atoi(value);
-        if (range < *min) {
-            printf("max id should be larger than min id\n");
-            return -1;
-        }
-        *offset = range - *min + 1;
-        debug("range = %d", *offset);
-    }
-    else {
-        printf("argument should be in the form of min-max\n");
-        return -1;
-    }
-
-    return 0;
-
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'l':
-        gL1CacheEnabled = atoi(optarg);
-        break;
-            
-    case 'g':    // GID range
-        return parse_range( &gid_min, &gid_range, optarg);
-        break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-// moved template init from benchmark_initworker -> benchmark_initrun
-//
-int
-benchmark_initrun()
-{
-    debug("\nbenchmark_initrun");
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i, err;
-    struct group *grp = NULL;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-        gid_t gid = gid_min + random() % gid_range ;
-
-        if (lm_optT > 1) {
-            struct group gd;
-            struct group *grp_ptr = &gd;
-            struct group *tmp_ptr;
-            char gbuf[BUFSIZE];
-
-            err = getgrgid_r( gid, grp_ptr, gbuf, BUFSIZE, &tmp_ptr);
-            if (err) {
-                debug("error: GID %d -> %s", gid, strerror(err));
-                res->re_errors++;
-            }
-            else if (!tmp_ptr) {
-                debug("not found: GID %d", gid);
-                res->re_errors++;
-            }
-        }
-        else {
-            errno = 0;
-            grp = getgrgid( gid );
-
-            if (!grp) {
-                if (errno) {
-                    debug("error: GID %d -> %s", gid, strerror(errno));
-                    res->re_errors++;
-                }
-                else {
-                    debug("not found: GID %d", gid);
-                    res->re_errors++;
-                }
-            }
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun ");
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getgrnam.c b/tools/tests/libMicro/apple/getgrnam.c
deleted file mode 100644 (file)
index 7d50a48..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <grp.h>
-#include <uuid/uuid.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    getgrnam -E  -L -S -W -B 200 -C 10 -r 10
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -r is the number of total groups (from "local_test_group1" to "local_test_group#")
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-// temporary buffer size
-#define BUFSIZE 200
-
-// the number of record lookup to issue is covered by standard option optB
-static int  optRecords =    10;  // the number of total records
-
-// This will use local users (local_test_*)
-static char *default_gprefix = "ds_test_group";
-
-#define GROUPNAME_LEN  30
-static char *grpname_list;
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "l:r:g:");
-
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n     ------- getgrnam specific options (default: *)\n"
-                "       [-r total number of group records (10*)]\n"
-                "       [-g group prefix(ds_test_group)]\n"
-                "\n" );
-    return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'r':    // total number of records. default is 100
-        optRecords = atoi(optarg);
-        debug("optRecords = %d\n", optRecords);
-        break;
-
-    case 'l':
-        gL1CacheEnabled = atoi(optarg);
-        break;
-
-    case 'g':  // base name for the groups to use
-       default_gprefix = strdup(optarg);
-       debug("default_gprefix = %s\n", default_gprefix);
-       break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-// moved template init from benchmark_initworker -> benchmark_initrun
-//  since username_list is static across threads and processes
-//
-int
-benchmark_initrun()
-{
-    int i;
-
-    debug("\nbenchmark_initrun");
-
-    // create an array of usernames to use in benchmark before their use
-    // realtime generation in benchmark effects performance measurements
-    grpname_list = malloc( optRecords * GROUPNAME_LEN );
-    if (!grpname_list) {
-        debug ("malloc error");
-        exit (1);
-    }
-
-    for (i = 0; i < optRecords; i++) {
-        sprintf(&grpname_list[i*GROUPNAME_LEN], "%s%d", default_gprefix, i+1);
-        debug("creating group name %s", &grpname_list[i*GROUPNAME_LEN]);
-    }
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int          i, err;
-    struct group *grp = NULL;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    srandom(getpid());
-
-    for (i = 0; i < lm_optB; i++) {
-        int index = (random() % optRecords) * GROUPNAME_LEN;
-
-        if (lm_optT > 1) {
-            struct group gd;
-            struct group *grp_ptr = &gd;
-            struct group *tmp_ptr;
-            char gbuf[BUFSIZE];
-
-            err = getgrnam_r( &grpname_list[index], grp_ptr, gbuf, BUFSIZE, &tmp_ptr);
-            // non-NULL err means failure and NULL result ptr means no matching
-            // entry
-            if (err) {
-                debug("error: %s -> %s",  &grpname_list[index], strerror(err));
-                res->re_errors++;
-            }
-            else if ( !tmp_ptr) {
-                debug("not found: %s",  &grpname_list[index] );
-                res->re_errors++;
-            }
-        }
-        else {
-            errno = 0;
-            grp = getgrnam( &grpname_list[index] );
-
-            if (!grp) {
-                if (errno) {
-                    debug("error: %s -> %s", &grpname_list[index], strerror(errno));
-                    res->re_errors++;
-                }
-                else {
-                    debug("not found: %s",  &grpname_list[index] );
-                    res->re_errors++;
-                }
-            }
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finiworker: deallocating structures");
-
-    free (grpname_list);
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getppid.c b/tools/tests/libMicro/apple/getppid.c
deleted file mode 100644 (file)
index ac775eb..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#ifdef __sun
-#pragma ident  "@(#)getppid.c  1.0     06/20/06 Apple Inc."
-#endif
-
-/*
- * getpid
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "../libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures getppid()");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i ++) {
-               (void) getppid();
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/getpwent.c b/tools/tests/libMicro/apple/getpwent.c
deleted file mode 100644 (file)
index 49df77e..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <pwd.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    getpwent -E  -L -S -W -B 200 -C 100
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-//
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-
-    (void) sprintf(lm_optstr, "l:");
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    return (0);
-}
-
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-    
-    switch (opt) {
-        case 'l':
-            gL1CacheEnabled = atoi(optarg);
-            break;
-    }
-    
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-//
-int
-benchmark_initrun()
-{
-    debug("\nbenchmark_initrun");
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i;
-    struct passwd *passwd;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-
-        errno = 0;      // this is needed explicitly due to getpwent() design
-        passwd = getpwent();
-
-        if (!passwd) {
-            if (errno) {
-                debug("error: %s", strerror(errno));
-                res->re_errors++;
-            }
-            else {
-                // will not counted toward libmicro error
-                setpassent(1);  // rewind to the beginning of passwd file
-            }
-        }
-        else {
-            debug("pw_name: %s", passwd->pw_name);
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun ");
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getpwnam.c b/tools/tests/libMicro/apple/getpwnam.c
deleted file mode 100644 (file)
index 3db5e6c..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <membership.h>
-#include <pwd.h>
-#include <uuid/uuid.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    getpwnam -E  -L -S -W -B 200 -C 10 -c 100 -r 300 -U test_user_
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -r is the number of total users
-// -c is the cache hit rate for lookup. set to 10%, you need -c 10.
-//                ie. -B 100 -c 50 -r 1000 -C 200 (out of 1000 records, I want 50%
-//                     lookup, and batch size is 100. 
-//                     To get 50% cache hit rate, you need 500 record lookups.
-//                     Batch size will be adjusted to 500 to get 500 record
-//                     lookup in each benchmark. If -r size is smaller than -B,
-//                     then -B will not be adjusted. 
-// -u prefix: the user name prefix to use in front the user number as the
-//             login name to lookup
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-// temporary buffer size
-#define BUFSIZE 200
-
-// the number of record lookup to issue is covered by standard option optB
-static int  optRecords =    100;  // the number of total records
-static int  optCachehit =   100;  // specify cache hit rate (% of record re-lookup)
-
-// This will use local users (local_test_*)
-static char *default_uprefix = "local_test_";
-
-#define USERNAME_LEN   20
-static char *username_list;
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "l:c:r:u:");
-
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n     ------- getpwnam specific options (default: *)\n"
-                "       [-c hitrate%% (100%%*)]\n"
-                "       [-r total number of records (100*)]\n"
-               "       [-u username_prefix (local_test_)]\n"
-                "\n" );
-    return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'c':    // cache hit rate. 100% means lookup the same records over and over
-        optCachehit = atoi(optarg);
-        debug("optCachehit = %d\n", optCachehit);
-        if (optCachehit > 100 || optCachehit < 0) {
-            printf("cache hit rate should be in between 0%% and 100%%");
-            return (-1);
-        }
-        break;
-
-    case 'l':
-        gL1CacheEnabled = atoi(optarg);
-        break;
-
-    case 'r':    // total number of records. default is 100
-        optRecords = atoi(optarg);
-        debug("optRecords = %d\n", optRecords);
-        break;
-
-    case 'u':
-       default_uprefix = strdup(optarg);
-       debug("default_uprefix = %s\n", default_uprefix);
-       break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-// moved template init from benchmark_initworker -> benchmark_initrun
-//  since username_list is static across threads and processes
-//
-
-int
-benchmark_initrun()
-{
-    int i;
-
-    debug("\nbenchmark_initrun");
-
-    // Adjust # of record lookups to reflect cache hit rate
-    if (optCachehit < 100) {
-        optRecords  = (int) ((float) optRecords * ((float) optCachehit / 100));
-        debug("# of records adjusted to %d for cache hit rate %d%%\n", optRecords, optCachehit);
-    }
-
-    // if batch size (one benchmark run) is less than the number records, adjust
-    // it to match the number record lookups in one batch run
-    if (lm_optB < optRecords) {
-        lm_optB = optRecords;
-        debug("Adjusting batch size to %d to match the lookups required in benchmark run\n", lm_optB);
-    }
-
-    // create an array of usernames to use in benchmark before their use
-    // realtime generation in benchmark effects performance measurements
-    username_list = malloc( optRecords * USERNAME_LEN );
-    if (!username_list) {
-        debug ("malloc error");
-        exit (1);
-    }
-
-    for (i = 0; i < optRecords; i++) {
-        sprintf(&username_list[i*USERNAME_LEN], "%s%d", default_uprefix, i+1);
-        // debug("creating username %s", &username_list[i*USERNAME_LEN]);
-    }
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i, err;
-    struct passwd *passwd = NULL;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-        int index = (random() % optRecords) * USERNAME_LEN;
-
-        if (lm_optT > 1) {
-            struct passwd pd;
-            struct passwd *pwd_ptr = &pd;
-            struct passwd *tmp_ptr;
-            char pbuf[BUFSIZE];
-
-            err = getpwnam_r( &username_list[index], pwd_ptr, pbuf, BUFSIZE, &tmp_ptr);
-            if (err) {
-                printf("error: %s -> %s", &username_list[index], strerror(err));
-                res->re_errors++;
-            }
-            else if (!tmp_ptr) {
-                debug("not found: %s", &username_list[index]);
-                res->re_errors++;
-            }
-        }
-        else {
-            errno = 0;
-            passwd = getpwnam( &username_list[index] );
-
-            if (!passwd) {
-                if (errno) {
-                    debug("error: %s -> %s", &username_list[index], strerror(errno));
-                    res->re_errors++;
-                }
-                else {
-                    debug("not found: %s", &username_list[index]);
-                    res->re_errors++;
-                }
-            }
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun: deallocating structures");
-
-    free (username_list);
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/getpwuid.c b/tools/tests/libMicro/apple/getpwuid.c
deleted file mode 100644 (file)
index c331491..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <pwd.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    getpwuid -E  -L -S -W -B 200 -C 10 -c 100 -u 5000-5200
-//
-//      libMicro default benchmark run options are "-E -L -S -W -C 200"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -c is the cache hit rate for lookup. set to 10%, you need -c 10.
-//                ie. -B 100 -c 50 -u 5000-5199
-//                     out of 200 UIDs, I want 50% cache hit, and batch size is 100. 
-// -u uid range in the form of "min-max". For example, -u 5000-5200
-//
-
-extern int gL1CacheEnabled;
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-// temporary buffer size
-#define BUFSIZE 200
-#define INVALID_ID  -1
-
-static uid_t  uid_min = INVALID_ID;
-static int    uid_range = 0;  // uid_max = uid_min + uid_range
-
-// the number of record lookup to issue is covered by standard option optB
-static int    optCachehit =   100;  // specify cache hit rate (% of record re-lookup)
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr, "l:c:u:");
-
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n     ------- getpwuid specific options (default: *)\n"
-                "       [-c hitrate%% (100%%*)]\n"
-                "       [-u UID range (min-max)]\n"
-                "       [-l]\n"
-                "\n" );
-    return (0);
-}
-
-int
-parse_range(uid_t *min, int *offset, char *buf)
-{
-    char *value, *tmp_ptr = strdup(buf);
-    int range=0;
-    debug("parse_range");
-
-    value = strsep(&tmp_ptr, "-");
-    *min = atoi(value);
-    debug("min = %d", *min);
-    if (tmp_ptr) {
-        value = strsep(&tmp_ptr, "-");
-        range = atoi(value);
-        if (range < *min) {
-            printf("max id should be larger than min id\n");
-            return -1;
-        }
-        *offset = range - *min + 1;
-        debug("range = %d", *offset);
-    }
-    else {
-        printf("argument should be in the form of min-max\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'c':    // cache hit rate. 100% means lookup the same records over and over
-        optCachehit = atoi(optarg);
-        debug("optCachehit = %d\n", optCachehit);
-        if (optCachehit > 100 || optCachehit < 0) {
-            printf("cache hit rate should be in between 0%% and 100%%");
-            return (-1);
-        }
-        break;
-            
-    case 'l':
-        gL1CacheEnabled = atoi(optarg);
-        break;
-
-    case 'u':    // UID range
-        return parse_range( &uid_min, &uid_range, optarg);
-        break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-// moved template init from benchmark_initworker -> benchmark_initrun
-//  since username_list is static across threads and processes
-//
-int
-benchmark_initrun()
-{
-    uid_t i, range;
-    struct passwd *passwd = NULL;
-
-    debug("\nbenchmark_initrun");
-
-    // To satisfy cache hit rate, lookup cachehit percentage of the UIDs here 
-    if (optCachehit < 100) {
-    
-        range = (int) ((float) uid_range * ((float) optCachehit / 100));
-        for (i = uid_min; i < uid_min+range; i++)
-            passwd = getpwuid( i );
-    }
-
-    return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i, err;
-    struct passwd *passwd = NULL;
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-        uid_t uid = uid_min + random() % uid_range ;
-
-        // XXX No need to use getpwuid_r() since getpwuid() is already thread-safe
-        // so it depends on what you want to exercise
-        if (lm_optT > 1) {
-            struct passwd pd;
-            struct passwd *pwd_ptr = &pd;
-            struct passwd *tmp_ptr;
-            char pbuf[BUFSIZE];
-
-            err = getpwuid_r( uid, pwd_ptr, pbuf, BUFSIZE, &tmp_ptr );
-            if (err) {
-                debug("error: %s", strerror(err));
-                res->re_errors++;
-            }
-            else if (!tmp_ptr) {
-                debug("not found: UID %d", uid);
-                res->re_errors++;
-            }
-        }
-        else {
-            errno = 0;
-            passwd = getpwuid( uid );
-
-            if (!passwd) {
-                if (errno) {
-                    debug("error: %s", strerror(errno));
-                    res->re_errors++;
-                }
-                else {
-                    debug("not found: UID %d", uid);
-                    res->re_errors++;
-                }
-            }
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    // tsd_t    *ts = (tsd_t *)tsd;
-    debug("benchmark_finirun ");
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/lb_mmtest.c b/tools/tests/libMicro/apple/lb_mmtest.c
deleted file mode 100644 (file)
index 2629ebe..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lb_mmtest.c        1.0     08/21/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <mach/boolean.h>
-#include <mach/mach_error.h>
-#include <mach/mach.h>
-#include <mach/notify.h>
-#include <servers/bootstrap.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/signal.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-    int server_mode;
-    boolean_t verbose;
-    boolean_t oneway;
-    int overwrite;
-    int msg_type;
-    int num_ints;
-    int num_msgs;
-    const char *server_port_name;
-    mach_port_t server_port;
-    mach_port_t reply_port;
-    int request_msg_size;
-    void *request_msg;
-    int reply_msg_size;
-    void *reply_msg;
-    void *ints;
-    long pid;
-} tsd_t;
-
-static boolean_t       opt_verbose;
-static boolean_t       opt_oneway;
-static int                     opt_num_msgs;
-static int                     opt_msg_type;
-static int                     opt_num_ints;
-static char *          opt_server_port_name;
-
-#pragma mark *** definitions from MMTest.c
-/*
- *     These variables were taken from MMtest.c
- */
-typedef struct {
-    mach_msg_header_t  header;
-    mach_msg_trailer_t trailer;                // subtract this when sending
-} ipc_trivial_message;
-
-typedef struct {
-    mach_msg_header_t  header;
-    u_int32_t          numbers[0];
-    mach_msg_trailer_t trailer;                // subtract this when sending
-} ipc_inline_message;
-
-typedef struct {
-    mach_msg_header_t          header;
-    mach_msg_body_t            body;
-    mach_msg_ool_descriptor_t  descriptor;
-    mach_msg_trailer_t         trailer;        // subtract this when sending
-} ipc_complex_message;
-
-void signal_handler(int sig) {
-}
-
-enum {
-    msg_type_trivial = 0,
-    msg_type_inline = 1,
-    msg_type_complex = 2
-};
-
-void server(void *tsd);
-void client(void *tsd);
-
-#pragma mark *** routines from MMTest.c
-/*
- *     These routines were taken from MMtest.c
- */
-void server(void *tsd) {
-    mach_msg_header_t *request;
-    mach_msg_header_t *reply;
-    mach_msg_option_t option;
-    kern_return_t ret;
-
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-    request = (mach_msg_header_t *)ts->request_msg;
-
-    reply = (mach_msg_header_t *)ts->reply_msg;
-
-#ifndef OPTIMIZED_SERVER
-    for (;;) {
-#endif /* !OPTIMIZED_SERVER */
-
-       if (ts->verbose) printf("Awaiting message\n");
-       option = MACH_RCV_MSG|MACH_RCV_INTERRUPT|MACH_RCV_LARGE;
-       ret = mach_msg(request,  
-                      option,
-                      0,
-                      ts->request_msg_size,  
-                      ts->server_port,
-                      MACH_MSG_TIMEOUT_NONE,
-                      MACH_PORT_NULL);
-
-#ifdef OPTIMIZED_SERVER
-    for (;;) {
-       mach_msg_header_t *tmp;
-#endif /* OPTIMIZED_SERVER */
-
-       if (MACH_MSG_SUCCESS != ret)
-               break;
-       if (ts->verbose) printf("Received message\n");
-       if (request->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
-               ipc_complex_message *complex_request;
-
-               complex_request = (ipc_complex_message *)ts->request_msg;
-               ret = vm_deallocate(mach_task_self(),  
-                                   (vm_address_t)complex_request->descriptor.address,  
-                                   complex_request->descriptor.size);
-       }
-       if (1 == request->msgh_id) {
-               if (ts->verbose) printf("Sending reply\n");
-               reply->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0);
-               reply->msgh_size = ts->reply_msg_size;
-               reply->msgh_remote_port = request->msgh_remote_port;
-               reply->msgh_local_port = MACH_PORT_NULL;
-               reply->msgh_id = 2;
-
-#ifdef OPTIMIZED_SERVER
-               option = MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_INTERRUPT|MACH_RCV_LARGE;
-       } else {
-               option = MACH_RCV_MSG|MACH_RCV_INTERRUPT|MACH_RCV_LARGE;
-       }
-
-       ret = mach_msg( reply,
-                       option,
-                       ts->reply_msg_size,
-                       ts->request_msg_size,
-                       ts->server_port,
-                       MACH_MSG_TIMEOUT_NONE,  
-                       MACH_PORT_NULL);
-       tmp = reply;
-       reply = request;
-       request = tmp;
-#else /* !OPTIMIZED_SERVER */
-               ret = mach_msg(reply,
-                              MACH_SEND_MSG,
-                              ts->reply_msg_size,
-                              0,
-                              MACH_PORT_NULL,
-                              MACH_MSG_TIMEOUT_NONE,
-                              MACH_PORT_NULL);
-               if (ret != MACH_MSG_SUCCESS)
-                       break;
-        }
-#endif /* !OPTIMIZED_SERVER */
-    }
-
-    if (MACH_RCV_INTERRUPTED != ret) {
-       mach_error("mach_msg: ", ret);
-               exit(1);
-    }
-}
-
-void client(void *tsd) {
-       mach_msg_header_t *request;
-       mach_msg_header_t *reply;
-       mach_msg_option_t option;
-       kern_return_t ret;
-       int idx;
-
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-#ifdef SWAP_BUFFERS
-       mach_msg_header_t *tmp;
-#endif
-
-       request = (mach_msg_header_t *)ts->request_msg;
-       reply = (mach_msg_header_t *)ts->reply_msg;
-       
-    for (idx = 0; idx < ts->num_msgs; idx++) {
-       request->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 
-                                           MACH_MSG_TYPE_MAKE_SEND_ONCE);
-       request->msgh_size = ts->request_msg_size;
-       request->msgh_remote_port = ts->server_port;
-       request->msgh_local_port = ts->reply_port;
-
-       if (ts->msg_type == msg_type_complex) {
-           ipc_complex_message *complexmsg = (ipc_complex_message *)request;
-
-           request->msgh_bits |=  MACH_MSGH_BITS_COMPLEX;
-           complexmsg->body.msgh_descriptor_count = 1;
-           complexmsg->descriptor.address =  ts->ints;
-           complexmsg->descriptor.size = ts->num_ints * sizeof(u_int32_t);
-           complexmsg->descriptor.deallocate = FALSE;
-           complexmsg->descriptor.copy = MACH_MSG_VIRTUAL_COPY;
-           complexmsg->descriptor.type =  MACH_MSG_OOL_DESCRIPTOR;
-       }
-
-       if (ts->oneway) {
-           request->msgh_id = 0;
-           option = MACH_SEND_MSG;
-       } else {
-           request->msgh_id = 1;
-           option = MACH_SEND_MSG|MACH_RCV_MSG;
-       }
-
-       if (ts->verbose) printf("Sending request\n");
-#ifdef SWAP_BUFFERS
-       ret = mach_msg( request,
-                       option,
-                       ts->request_msg_size,
-                       ts->reply_msg_size,
-                       ts->reply_port,
-                       MACH_MSG_TIMEOUT_NONE,
-                       MACH_PORT_NULL);
-       if (MACH_MSG_SUCCESS != ret) {
-           mach_error("client: mach_msg: ", ret);
-           fprintf(stderr, "bailing after %u iterations\n", idx);
-           exit(1);
-       }
-       tmp = request;
-       request = reply;
-       reply = tmp;
-#else
-       ret = mach_msg_overwrite(request,
-                                option,
-                                ts->request_msg_size,
-                                ts->reply_msg_size,
-                                ts->reply_port,
-                                MACH_MSG_TIMEOUT_NONE,
-                                MACH_PORT_NULL,
-                                reply,
-                                0);
-       if (MACH_MSG_SUCCESS != ret) {
-           mach_error("client: mach_msg_overwrite: ", ret);
-           fprintf(stderr, "bailing after %u iterations\n", idx);
-           exit(1);
-       }
-#endif
-       if (ts->verbose && !ts->oneway) printf("Received reply\n");
-    }
-}
-
-
-#pragma mark *** Darbench routines
-
-/*
- *     These routines are required by darbench
- */
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       long    pid;
-       tsd_t   *ts = (tsd_t *)tsd;
-       
-    ts->server_mode = -1;
-    ts->verbose = opt_verbose;
-    ts->oneway = opt_oneway;
-    ts->overwrite = 0;
-    ts->msg_type = opt_msg_type;
-    ts->num_ints = opt_num_ints;
-    ts->num_msgs = opt_num_msgs;
-    ts->server_port_name = opt_server_port_name;
-    ts->server_port = MACH_PORT_NULL;
-    ts->reply_port = MACH_PORT_NULL;
-    ts->request_msg = NULL;
-    ts->request_msg_size = 0;
-    ts->reply_msg = NULL;
-    ts->reply_msg_size = 0;
-
-       switch (ts->msg_type) {
-       case msg_type_trivial:
-         ts->request_msg_size = sizeof(ipc_trivial_message);
-               break;
-
-       case msg_type_inline:
-         ts->request_msg_size = sizeof(ipc_inline_message) +  
-               sizeof(u_int32_t) * ts->num_ints;
-               break;
-
-       case msg_type_complex:
-         ts->request_msg_size = sizeof(ipc_complex_message);
-         ts->ints = malloc(sizeof(u_int32_t) * ts->num_ints);
-         break;
-       }
-
-    ts->request_msg = malloc(ts->request_msg_size);
-    ts->reply_msg = malloc(ts->reply_msg_size);
-
-    if (ts->server_mode) {
-               kern_return_t ret = 0;
-               mach_port_t bsport;
-
-               ts->reply_msg_size -= sizeof(mach_msg_trailer_t);
-               ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,  
-                                        &(ts->server_port));
-               if (KERN_SUCCESS != ret) {
-                       mach_error("mach_port_allocate(): ", ret);
-                       exit(1);
-               }
-               ret = mach_port_insert_right(mach_task_self(), ts->server_port,  
-                ts->server_port, MACH_MSG_TYPE_MAKE_SEND);
-               if (KERN_SUCCESS != ret) {
-                       mach_error("mach_port_insert_right(): ", ret);
-                       exit(1);
-               }
-               ret = task_get_bootstrap_port(mach_task_self(), &bsport);
-               if (KERN_SUCCESS != ret) {
-                       mach_error("task_get_bootstrap_port(): ", ret);
-                       exit(1);
-               }
-               ret = bootstrap_check_in(bsport, (char *)ts->server_port_name,  
-                       &ts->server_port);
-               if (KERN_SUCCESS != ret) {
-                       mach_error("bootstrap_register(): ", ret);
-                       exit(1);
-               }
-    } else {   /* client mode */
-               kern_return_t ret = 0;
-               mach_port_t bsport;
-
-               ts->request_msg_size -= sizeof(mach_msg_trailer_t);
-
-               ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,  
-                                        &(ts->reply_port));
-               if (KERN_SUCCESS != ret) {
-                       mach_error("mach_port_allocate(): ", ret);
-                       exit(1);
-               }
-
-               ret = task_get_bootstrap_port(mach_task_self(), &bsport);
-               if (KERN_SUCCESS != ret) {
-                       mach_error("task_get_bootstrap_port(): ", ret);
-                       exit(1);
-               }
-               ret = bootstrap_look_up(bsport, (char *)ts->server_port_name,  
-                       &(ts->server_port));
-               if (KERN_SUCCESS != ret) {
-                       mach_error("bootstrap_look_up(): ", ret);
-                       exit(1);
-               }
-    }
-    
-    if (ts->verbose) {
-               if (ts->server_mode) {
-                       printf("Server waiting for IPC messages from client on port  '%s'.\n",
-                              ts->server_port_name);
-               } else {
-                       printf("Client sending %d %s IPC messages to port '%s' in %s  mode.\n",
-                              ts->num_msgs, (ts->msg_type == msg_type_inline) ? "inline" :  
-                              ((ts->msg_type == msg_type_complex) ? "complex" : "trivial"),  
-                              ts->server_port_name, (ts->oneway ? "oneway" : "rpc"));
-               }
-    }
-
-       pid = fork();
-       switch (pid) {
-               case 0:
-                       server(tsd);
-                       exit(0);
-                       break;
-               case -1:
-                       return (-1);
-               default:
-                       ts->pid = pid;
-                       break;
-               }
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       (void) fprintf(stderr, "benchmark_finirun\n");
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *      ...and the framework will throw an error
-        *      lm_optstr has two kinds of arguments, boolean (single
-        *      lower case character) and with an argument (single lower
-        *      case character plus a :, indicating the next option is
-        *      the argument)
-        *
-        */
-       (void) sprintf(lm_optstr, "voc:t:n:p:");
-       /*
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-       "    -v\t\tbe verbose\n"
-       "    -o\t\tdo not request return reply (client)\n"
-       "    -c num\t\tnumber of messages to send (client)\n"
-       "    -t trivial|inline|complex\ttype of messages to  send (client)\n"
-       "    -n num\tnumber of 32-bit ints to send in  messages\n"
-       "\t\t\t(client's value must be <= the server's)\n"
-       "    -p portname\tname of port on which to communicate\n"
-       "\t\t\t(client and server must use the same value)\n");
-
-       opt_verbose = FALSE;
-       opt_oneway = FALSE;
-       opt_num_msgs = 10000;
-       opt_msg_type = msg_type_trivial;
-       opt_num_ints = 64;
-       opt_server_port_name = malloc(32);
-       strcpy(opt_server_port_name, "TEST");
-
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       free(opt_server_port_name);
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       kill(ts->pid, SIGKILL);
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-//     tsd_t                   *ts = (tsd_t *)tsd;
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       (void) fprintf(stderr, "benchmark_optswitch\n");
-       
-       switch (opt) {
-       case 'v':
-               opt_verbose = TRUE;
-               break;
-       case 'o':
-               opt_oneway = TRUE;
-               break;
-       case 'c':
-               opt_num_msgs = sizetoint(optarg);
-               break;
-       case 't':
-               if ( 0 == strcmp("trivial", optarg) )
-                       opt_msg_type = msg_type_trivial;
-               else if ( 0 == strcmp("inline", optarg) )
-                       opt_msg_type = msg_type_inline;
-               else if ( 0 == strcmp("complex", optarg) )
-                       opt_msg_type = msg_type_complex;
-               else {
-                       (void) fprintf(stderr, "incorrect argument for message type %s\n", optarg);
-                       return (-1);
-               }
-               break;
-       case 'n':
-               opt_num_ints = sizetoint(optarg);
-               break;
-       case 'p':
-               strncpy(opt_server_port_name, optarg, 32);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-//     tsd_t                   *ts = (tsd_t *)tsd;
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) fprintf(stderr, "benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-//     tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       
-       for (i = 0; i < lm_optB; i++) {
-               client(tsd);
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lm_null_call.c b/tools/tests/libMicro/apple/lm_null_call.c
deleted file mode 100644 (file)
index 825c14c..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)socket.c   1.3     05/08/04 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       int fd;
-       char* file;
-} tsd_t;
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "t:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *       will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-t int (default 1)]\n"
-           "notes: measures nothing\n");
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       (void) fprintf(stderr, "benchmark_fini\n");
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "null_call (getppid)\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       int                     i;
-       
-       for (i = 0; i < lm_optB; i++) {
-               /*
-                *      just to show that ts really contains state
-                */
-               getppid();
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_bw_file_rd.c b/tools/tests/libMicro/apple/lmbench_bw_file_rd.c
deleted file mode 100644 (file)
index d5a4f95..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_bw_file_rd.c       1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-// add additional headers needed here.
-#include <fcntl.h>
-
-#include "../libmicro.h"
-
-#if DEBUG
-# define debug(fmt, args...)   (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       char filename[256];
-       int fd;
-       int clone;
-       bool open_read_close;
-} tsd_t;
-
-/*
- * You can have any lower-case option you want to define.
- * options are specified in the lm_optstr as either a 
- * single lower-case letter, or a single lower case letter 
- * with a colon after it.  In this example, you can optionally
- * specify -c {str} -e or -t {number}  
- *    -c takes a string (quote the string if blanks)
- *    -e is a boolean 
- *    -t takes a numeric
- * argument.
- */
-static char    optf[256]; 
-static bool    opti = false;   // io_only or read and i/o (default read and i/o)
-
-#define        CHK(x)          if ((int)(x) == -1) { perror(#x); exit(1); }
-#ifndef        MIN
-#define        MIN(a, b)       ((a) < (b) ? (a) : (b))
-#endif
-
-#define        TYPE    int
-#define        MINSZ   (sizeof(TYPE) * 128)
-
-void   *buf;           /* do the I/O here */
-size_t xfersize;       /* do it in units of this */
-size_t count;          /* bytes to move (can't be modified) */
-
-/* analogous to bzero, bcopy, etc., except that it just reads
- * data into the processor
- */
-long
-bread(void* buf, long nbytes)
-{
-       long sum = 0;
-       register long *p, *next;
-       register char *end;
-
-       p = (long*)buf;
-       end = (char*)buf + nbytes;
-       for (next = p + 128; (void*)next <= (void*)end; p = next, next += 128) {
-               sum +=
-                       p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7]+
-                       p[8]+p[9]+p[10]+p[11]+p[12]+p[13]+p[14]+
-                       p[15]+p[16]+p[17]+p[18]+p[19]+p[20]+p[21]+
-                       p[22]+p[23]+p[24]+p[25]+p[26]+p[27]+p[28]+
-                       p[29]+p[30]+p[31]+p[32]+p[33]+p[34]+p[35]+
-                       p[36]+p[37]+p[38]+p[39]+p[40]+p[41]+p[42]+
-                       p[43]+p[44]+p[45]+p[46]+p[47]+p[48]+p[49]+
-                       p[50]+p[51]+p[52]+p[53]+p[54]+p[55]+p[56]+
-                       p[57]+p[58]+p[59]+p[60]+p[61]+p[62]+p[63]+
-                       p[64]+p[65]+p[66]+p[67]+p[68]+p[69]+p[70]+
-                       p[71]+p[72]+p[73]+p[74]+p[75]+p[76]+p[77]+
-                       p[78]+p[79]+p[80]+p[81]+p[82]+p[83]+p[84]+
-                       p[85]+p[86]+p[87]+p[88]+p[89]+p[90]+p[91]+
-                       p[92]+p[93]+p[94]+p[95]+p[96]+p[97]+p[98]+
-                       p[99]+p[100]+p[101]+p[102]+p[103]+p[104]+
-                       p[105]+p[106]+p[107]+p[108]+p[109]+p[110]+
-                       p[111]+p[112]+p[113]+p[114]+p[115]+p[116]+
-                       p[117]+p[118]+p[119]+p[120]+p[121]+p[122]+
-                       p[123]+p[124]+p[125]+p[126]+p[127];
-       }
-       for (next = p + 16; (void*)next <= (void*)end; p = next, next += 16) {
-               sum +=
-                       p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7]+
-                       p[8]+p[9]+p[10]+p[11]+p[12]+p[13]+p[14]+
-                       p[15];
-       }
-       for (next = p + 1; (void*)next <= (void*)end; p = next, next++) {
-               sum += *p;
-       }
-       return sum;
-}
-
-void doit(int fd)
-{
-       size_t  size, chunk;
-
-       size = count;
-       chunk = xfersize;
-       while (size >= 0) {
-               if (size < chunk) chunk = size;
-               if (read(fd, buf, MIN(size, chunk)) <= 0) {
-                       break;
-               }
-               bread(buf, MIN(size, xfersize));
-               size -= chunk;
-       }
-}
-
-
-int
-benchmark_init()
-{
-       debug("benchmark_init");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "f:i");
-       /*
-        *      tsd_t is the state info struct that we pass around 
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "               [-f filename]\n"
-               "               [-i] io_only (no open/close)\n"
-           "notes: read and sum file via read(2) interface");
-       sprintf(optf, "/tmp/%d", (int)getpid());
-       return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- * the format was defined in the lm_optstr assignment
- * in benchmark_init
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       debug("benchmark_optswitch");
-       
-       switch (opt) {
-       case 'f':
-               strncpy(optf, optarg, 255);
-               debug("optf = %s\n", optf);
-               break;
-       case 'i':
-               opti = true;
-               debug("opti = %s\n", opte? "true": "false");
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       debug("benchmark_initrun");
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       strncpy(ts->filename, optf, 255);
-       ts->open_read_close = opti;
-       debug("benchmark_initworker: ts_once = %i\n",ts->ts_once);      
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       debug("benchmark_initbatch");
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      try not to initialize things here.  This is the main
-        *  loop of things to get timed.  Start a server in 
-        *  benchmark_initbatch
-        */
-       tsd_t   *ts = (tsd_t *)tsd;
-       int             i;
-       int             fd;
-       
-       debug("in to benchmark - optB = %i", lm_optB);
-       for (i = 0; i < lm_optB; i++) {
-               if (ts->open_read_close) {
-                       fd = open(ts->filename, O_RDONLY);
-                       doit(fd);
-                       close(fd);
-               } else {
-                       doit(fd);
-               }
-       }
-       res->re_count = i;
-       debug("out of benchmark - optB = %i", lm_optB);
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       debug("benchmark_finibatch");
-       return (0);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       debug("benchmark_finiworker");
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       debug("benchmark_result");
-       return (&result);
-}
-
-int
-benchmark_finirun()
-{
-       debug("benchmark_finirun");
-       return (0);
-}
-
-
-int
-benchmark_fini()
-{
-       debug("benchmark_fini");
-       return (0);
-}
-
diff --git a/tools/tests/libMicro/apple/lmbench_bw_mem.c b/tools/tests/libMicro/apple/lmbench_bw_mem.c
deleted file mode 100644 (file)
index 9963fe6..0000000
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-/*
- * To port to libmicro, I had to add options for
- * some items which were just arguments before.
- * -s is the size (more than 512)
- * -x is the command to execute (rd wr rdwr cp fwr frd fcp bzero bcopy)
- * see usage string for command options.
- */
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_bw_mem.c   1.0 20060814 Apple Inc."
-#endif
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "../libmicro.h"
-
-#define        TRIES           11      // value from bench.h in lmbench
-#define TYPE           int
-
-/* Added as part of the fix for <rdar://problem/7508837> */
-static volatile u_int64_t       use_result_dummy;
-void use_int(int result) { use_result_dummy += result; }
-
-/*
- * rd - 4 byte read, 32 byte stride
- * wr - 4 byte write, 32 byte stride
- * rdwr - 4 byte read followed by 4 byte write to same place, 32 byte stride
- * cp - 4 byte read then 4 byte write to different place, 32 byte stride
- * fwr - write every 4 byte word
- * frd - read every 4 byte word
- * fcp - copy every 4 byte word
- *
- * All tests do 512 byte chunks in a loop.
- *
- * XXX - do a 64bit version of this.
- */
-void   rd(iter_t iterations, void *cookie);
-void   wr(iter_t iterations, void *cookie);
-void   rdwr(iter_t iterations, void *cookie);
-void   mcp(iter_t iterations, void *cookie);
-void   fwr(iter_t iterations, void *cookie);
-void   frd(iter_t iterations, void *cookie);
-void   fcp(iter_t iterations, void *cookie);
-void   loop_bzero(iter_t iterations, void *cookie);
-void   loop_bcopy(iter_t iterations, void *cookie);
-void   init_overhead(iter_t iterations, void *cookie);
-void   init_loop(iter_t iterations, void *cookie);
-void   cleanup(iter_t iterations, void *cookie);
-
-typedef struct _state {
-       double  overhead;
-       size_t  nbytes;
-       int     need_buf2;
-       int     aligned;
-       TYPE    *buf;
-       TYPE    *buf2;
-       TYPE    *buf2_orig;
-       TYPE    *lastone;
-       size_t  N;
-} state_t;
-
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       double  overhead;
-       size_t  nbytes;
-       int     need_buf2;
-       int     aligned;
-       TYPE    *buf;
-       TYPE    *buf2;
-       TYPE    *buf2_orig;
-       TYPE    *lastone;
-       size_t  N;
-       int     parallel;
-       int     warmup;
-       int     repetitions;
-} tsd_t;
-
-
-static int     optp = 1;
-static int     optw = 0;
-static int     optn = TRIES;
-static int     opt_size = 0;
-static char    *opt_what;      // maximum "what" command string size
-
-void
-init_overhead(iter_t iterations, void *cookie)
-{
-}
-
-void
-init_loop(iter_t iterations, void *cookie)
-{
-       tsd_t                   *ts = (tsd_t *)cookie;
-
-       if (iterations) return;
-
-    ts->buf = (TYPE *)valloc(ts->nbytes);
-       ts->buf2_orig = NULL;
-       ts->lastone = (TYPE*)ts->buf - 1;
-       ts->lastone = (TYPE*)((char *)ts->buf + ts->nbytes - 512);
-       ts->N = ts->nbytes;
-
-       if (!ts->buf) {
-               perror("malloc");
-               exit(1);
-       }
-       bzero((void*)ts->buf, ts->nbytes);
-
-       if (ts->need_buf2 == 1) {
-               ts->buf2_orig = ts->buf2 = (TYPE *)valloc(ts->nbytes + 2048);
-               if (!ts->buf2) {
-                       perror("malloc");
-                       exit(1);
-               }
-
-               /* default is to have stuff unaligned wrt each other */
-               /* XXX - this is not well tested or thought out */
-               if (ts->aligned) {
-                       char    *tmp = (char *)ts->buf2;
-
-                       tmp += 2048 - 128;
-                       ts->buf2 = (TYPE *)tmp;
-               }
-       }
-}
-
-void
-cleanup(iter_t iterations, void *cookie)
-{
-       tsd_t                   *ts = (tsd_t *)cookie;
-
-       if (iterations) return;
-
-       free(ts->buf);
-       if (ts->buf2_orig) free(ts->buf2_orig);
-}
-
-void
-rd(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *lastone = ts->lastone;
-       register int sum = 0;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           while (p <= lastone) {
-               sum += 
-#define        DOIT(i) p[i]+
-               DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
-               DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
-               DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
-               DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
-               DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) 
-               p[124];
-               p +=  128;
-           }
-       }
-       use_int(sum);
-}
-#undef DOIT
-
-void
-wr(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *lastone = ts->lastone;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           while (p <= lastone) {
-#define        DOIT(i) p[i] = 1;
-               DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
-               DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
-               DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
-               DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
-               DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) DOIT(124);
-               p +=  128;
-           }
-       }
-}
-#undef DOIT
-
-void
-rdwr(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *lastone = ts->lastone;
-       register int sum = 0;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           while (p <= lastone) {
-#define        DOIT(i) sum += p[i]; p[i] = 1;
-               DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
-               DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
-               DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
-               DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
-               DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) DOIT(124);
-               p +=  128;
-           }
-       }
-       use_int(sum);
-}
-#undef DOIT
-
-void
-mcp(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *lastone = ts->lastone;
-       TYPE* p_save = NULL;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           register TYPE *dst = ts->buf2;
-           while (p <= lastone) {
-#define        DOIT(i) dst[i] = p[i];
-               DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
-               DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
-               DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
-               DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
-               DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) DOIT(124);
-               p += 128;
-               dst += 128;
-           }
-           p_save = p;
-       }
-}
-#undef DOIT
-
-void
-fwr(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *lastone = ts->lastone;
-       TYPE* p_save = NULL;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           while (p <= lastone) {
-#define        DOIT(i) p[i]=
-               DOIT(0) DOIT(1) DOIT(2) DOIT(3) DOIT(4) DOIT(5) DOIT(6)
-               DOIT(7) DOIT(8) DOIT(9) DOIT(10) DOIT(11) DOIT(12)
-               DOIT(13) DOIT(14) DOIT(15) DOIT(16) DOIT(17) DOIT(18)
-               DOIT(19) DOIT(20) DOIT(21) DOIT(22) DOIT(23) DOIT(24)
-               DOIT(25) DOIT(26) DOIT(27) DOIT(28) DOIT(29) DOIT(30)
-               DOIT(31) DOIT(32) DOIT(33) DOIT(34) DOIT(35) DOIT(36)
-               DOIT(37) DOIT(38) DOIT(39) DOIT(40) DOIT(41) DOIT(42)
-               DOIT(43) DOIT(44) DOIT(45) DOIT(46) DOIT(47) DOIT(48)
-               DOIT(49) DOIT(50) DOIT(51) DOIT(52) DOIT(53) DOIT(54)
-               DOIT(55) DOIT(56) DOIT(57) DOIT(58) DOIT(59) DOIT(60)
-               DOIT(61) DOIT(62) DOIT(63) DOIT(64) DOIT(65) DOIT(66)
-               DOIT(67) DOIT(68) DOIT(69) DOIT(70) DOIT(71) DOIT(72)
-               DOIT(73) DOIT(74) DOIT(75) DOIT(76) DOIT(77) DOIT(78)
-               DOIT(79) DOIT(80) DOIT(81) DOIT(82) DOIT(83) DOIT(84)
-               DOIT(85) DOIT(86) DOIT(87) DOIT(88) DOIT(89) DOIT(90)
-               DOIT(91) DOIT(92) DOIT(93) DOIT(94) DOIT(95) DOIT(96)
-               DOIT(97) DOIT(98) DOIT(99) DOIT(100) DOIT(101) DOIT(102)
-               DOIT(103) DOIT(104) DOIT(105) DOIT(106) DOIT(107)
-               DOIT(108) DOIT(109) DOIT(110) DOIT(111) DOIT(112)
-               DOIT(113) DOIT(114) DOIT(115) DOIT(116) DOIT(117)
-               DOIT(118) DOIT(119) DOIT(120) DOIT(121) DOIT(122)
-               DOIT(123) DOIT(124) DOIT(125) DOIT(126) DOIT(127) 1;
-               p += 128;
-           }
-           p_save = p;
-       }
-}
-#undef DOIT
-
-void
-frd(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register int sum = 0;
-       register TYPE *lastone = ts->lastone;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           while (p <= lastone) {
-               sum +=
-#define        DOIT(i) p[i]+
-               DOIT(0) DOIT(1) DOIT(2) DOIT(3) DOIT(4) DOIT(5) DOIT(6)
-               DOIT(7) DOIT(8) DOIT(9) DOIT(10) DOIT(11) DOIT(12)
-               DOIT(13) DOIT(14) DOIT(15) DOIT(16) DOIT(17) DOIT(18)
-               DOIT(19) DOIT(20) DOIT(21) DOIT(22) DOIT(23) DOIT(24)
-               DOIT(25) DOIT(26) DOIT(27) DOIT(28) DOIT(29) DOIT(30)
-               DOIT(31) DOIT(32) DOIT(33) DOIT(34) DOIT(35) DOIT(36)
-               DOIT(37) DOIT(38) DOIT(39) DOIT(40) DOIT(41) DOIT(42)
-               DOIT(43) DOIT(44) DOIT(45) DOIT(46) DOIT(47) DOIT(48)
-               DOIT(49) DOIT(50) DOIT(51) DOIT(52) DOIT(53) DOIT(54)
-               DOIT(55) DOIT(56) DOIT(57) DOIT(58) DOIT(59) DOIT(60)
-               DOIT(61) DOIT(62) DOIT(63) DOIT(64) DOIT(65) DOIT(66)
-               DOIT(67) DOIT(68) DOIT(69) DOIT(70) DOIT(71) DOIT(72)
-               DOIT(73) DOIT(74) DOIT(75) DOIT(76) DOIT(77) DOIT(78)
-               DOIT(79) DOIT(80) DOIT(81) DOIT(82) DOIT(83) DOIT(84)
-               DOIT(85) DOIT(86) DOIT(87) DOIT(88) DOIT(89) DOIT(90)
-               DOIT(91) DOIT(92) DOIT(93) DOIT(94) DOIT(95) DOIT(96)
-               DOIT(97) DOIT(98) DOIT(99) DOIT(100) DOIT(101) DOIT(102)
-               DOIT(103) DOIT(104) DOIT(105) DOIT(106) DOIT(107)
-               DOIT(108) DOIT(109) DOIT(110) DOIT(111) DOIT(112)
-               DOIT(113) DOIT(114) DOIT(115) DOIT(116) DOIT(117)
-               DOIT(118) DOIT(119) DOIT(120) DOIT(121) DOIT(122)
-               DOIT(123) DOIT(124) DOIT(125) DOIT(126) p[127];
-               p += 128;
-           }
-       }
-       use_int(sum);
-}
-#undef DOIT
-
-void
-fcp(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *lastone = ts->lastone;
-
-       while (iterations-- > 0) {
-           register TYPE *p = ts->buf;
-           register TYPE *dst = ts->buf2;
-           while (p <= lastone) {
-#define        DOIT(i) dst[i]=p[i];
-               DOIT(0) DOIT(1) DOIT(2) DOIT(3) DOIT(4) DOIT(5) DOIT(6)
-               DOIT(7) DOIT(8) DOIT(9) DOIT(10) DOIT(11) DOIT(12)
-               DOIT(13) DOIT(14) DOIT(15) DOIT(16) DOIT(17) DOIT(18)
-               DOIT(19) DOIT(20) DOIT(21) DOIT(22) DOIT(23) DOIT(24)
-               DOIT(25) DOIT(26) DOIT(27) DOIT(28) DOIT(29) DOIT(30)
-               DOIT(31) DOIT(32) DOIT(33) DOIT(34) DOIT(35) DOIT(36)
-               DOIT(37) DOIT(38) DOIT(39) DOIT(40) DOIT(41) DOIT(42)
-               DOIT(43) DOIT(44) DOIT(45) DOIT(46) DOIT(47) DOIT(48)
-               DOIT(49) DOIT(50) DOIT(51) DOIT(52) DOIT(53) DOIT(54)
-               DOIT(55) DOIT(56) DOIT(57) DOIT(58) DOIT(59) DOIT(60)
-               DOIT(61) DOIT(62) DOIT(63) DOIT(64) DOIT(65) DOIT(66)
-               DOIT(67) DOIT(68) DOIT(69) DOIT(70) DOIT(71) DOIT(72)
-               DOIT(73) DOIT(74) DOIT(75) DOIT(76) DOIT(77) DOIT(78)
-               DOIT(79) DOIT(80) DOIT(81) DOIT(82) DOIT(83) DOIT(84)
-               DOIT(85) DOIT(86) DOIT(87) DOIT(88) DOIT(89) DOIT(90)
-               DOIT(91) DOIT(92) DOIT(93) DOIT(94) DOIT(95) DOIT(96)
-               DOIT(97) DOIT(98) DOIT(99) DOIT(100) DOIT(101) DOIT(102)
-               DOIT(103) DOIT(104) DOIT(105) DOIT(106) DOIT(107)
-               DOIT(108) DOIT(109) DOIT(110) DOIT(111) DOIT(112)
-               DOIT(113) DOIT(114) DOIT(115) DOIT(116) DOIT(117)
-               DOIT(118) DOIT(119) DOIT(120) DOIT(121) DOIT(122)
-               DOIT(123) DOIT(124) DOIT(125) DOIT(126) DOIT(127)
-               p += 128;
-               dst += 128;
-           }
-       }
-}
-
-void
-loop_bzero(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *p = ts->buf;
-       register size_t  N = ts->N;
-
-       while (iterations-- > 0) {
-               bzero(p, N);
-       }
-}
-
-void
-loop_bcopy(iter_t iterations, void *cookie)
-{      
-       tsd_t                   *ts = (tsd_t *)cookie;
-       register TYPE *p = ts->buf;
-       register TYPE *dst = ts->buf2;
-       register size_t  N = ts->N;
-
-       while (iterations-- > 0) {
-               bcopy(p,dst,N);
-       }
-}
-
-#pragma mark libmicro routines
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-    ts->buf = (TYPE *)valloc(ts->nbytes);
-       ts->buf2_orig = NULL;
-       ts->lastone = (TYPE*)ts->buf - 1;
-       ts->lastone = (TYPE*)((char *)ts->buf + ts->nbytes - 512);
-       ts->N = ts->nbytes;
-
-       if (!ts->buf) {
-               perror("malloc");
-               exit(1);
-       }
-       bzero((void*)ts->buf, ts->nbytes);
-
-       if (ts->need_buf2 == 1) {
-               ts->buf2_orig = ts->buf2 = (TYPE *)valloc(ts->nbytes + 2048);
-               if (!ts->buf2) {
-                       perror("malloc");
-                       exit(1);
-               }
-
-               /* default is to have stuff unaligned wrt each other */
-               /* XXX - this is not well tested or thought out */
-               if (ts->aligned) {
-                       char    *tmp = (char *)ts->buf2;
-
-                       tmp += 2048 - 128;
-                       ts->buf2 = (TYPE *)tmp;
-               }
-       }
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "p:w:n:s:x:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-       opt_what = (char *)malloc(30);
-
-       (void) sprintf(lm_usage,
-           "   [-p <parallelism>]\n"
-           "   [-w <warmup>]\n"
-           "   [-n <repetitions>]\n"
-           "   -s <size>\n"
-           "           <size> must be larger than 512"
-           "   -x what\n"
-           "           what: rd wr rdwr cp fwr frd fcp bzero bcopy\n"
-           "     [conflict] -- unknown option?\n"
-       );
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       free(opt_what);
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       free(ts->buf);
-       if (ts->buf2_orig) free(ts->buf2_orig);
-       return (0);
-}
-
-/* return -1 to display usage (i.e. if can't parse arguments */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       
-       switch (opt) {
-               case 'p':
-                       optp = sizetoint(optarg);
-                       if (optp <= 0) 
-                               return (-1);
-                       break;
-               case 'w':
-                       optw = sizetoint(optarg);
-                       break;
-               case 'n':
-                       optn = sizetoint(optarg);
-                       break;
-               case 's':
-                       opt_size = sizetoint(optarg);
-                       break;
-               case 'x':
-                       strcpy(opt_what, optarg);
-                       break;
-               default:
-                       return(-1);
-                       break;
-       }
-//     (void) fprintf(stderr, "optp = %i optw = %i optn = %i opt_size = %i\n",
-//                                             optp, optw, optn, opt_size);
-//     (void) fprintf(stderr, "opt_what = %s\n", opt_what);                                            
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       ts->parallel = optp;
-       ts->warmup = optw;
-       ts->repetitions = optn;
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       size_t  nbytes;
-       int     i;
-
-       ts->overhead = 0;
-
-
-       /* should have two, possibly three [indicates align] arguments left */
-       ts->aligned = ts->need_buf2 = 0;
-
-       nbytes = ts->nbytes = opt_size;
-       if (ts->nbytes < 512) { /* this is the number of bytes in the loop */
-               return(-1);
-       }
-
-       if (STREQ(opt_what, "cp") ||
-           STREQ(opt_what, "fcp") || STREQ(opt_what, "bcopy")) {
-               ts->need_buf2 = 1;
-       }
-       
-       for (i = 0 ; i < lm_optB ; i++)
-       {
-               if (STREQ(opt_what, "rd")) {
-                       rd( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "wr")) {
-                       wr( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "rdwr")) {
-                       rdwr( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "cp")) {
-                       mcp( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "frd")) {
-                       frd( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "fwr")) {
-                       fwr( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "fcp")) {
-                       fcp( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "bzero")) {
-                       loop_bzero( ts->repetitions, tsd ); 
-               } else if (STREQ(opt_what, "bcopy")) {
-                       loop_bcopy( ts->repetitions, tsd ); 
-               } else {
-                       return(-1);
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_bw_mmap_rd.c b/tools/tests/libMicro/apple/lmbench_bw_mmap_rd.c
deleted file mode 100644 (file)
index 656bbb1..0000000
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_bw_mmap_rd.c       1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-// add additional headers needed here.
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/mman.h>
-
-#include "../libmicro.h"
-
-#if DEBUG
-# define debug(fmt, args...)   (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       size_t  nbytes;
-       char    filename[_POSIX_PATH_MAX];
-       int     fd;
-       int     clone;
-       void    *buf;
-       bool open_read_close;
-} tsd_t;
-
-/*
- * You can have any lower-case option you want to define.
- * options are specified in the lm_optstr as either a 
- * single lower-case letter, or a single lower case letter 
- * with a colon after it.  In this example, you can optionally
- * specify -c {str} -e or -t {number}  
- *    -c takes a string (quote the string if blanks)
- *    -e is a boolean 
- *    -t takes a numeric
- * argument.
- */
-static char    optf[_POSIX_PATH_MAX]; 
-static int             opts = 1024;
-static bool    opti = false;   // io_only or read and i/o (default read and i/o)
-
-#ifdef MAP_FILE
-#      define  MMAP_FLAGS      MAP_FILE|MAP_SHARED
-#else
-#      define  MMAP_FLAGS      MAP_SHARED
-#endif
-
-#define        CHK(x)          if ((int)(x) == -1) { perror(#x); exit(1); }
-#ifndef        MIN
-#define        MIN(a, b)       ((a) < (b) ? (a) : (b))
-#endif
-
-#define        TYPE    int
-#define        MINSZ   (sizeof(TYPE) * 128)
-
-void   *buf;           /* do the I/O here */
-size_t xfersize;       /* do it in units of this */
-size_t count;          /* bytes to move (can't be modified) */
-
-/* analogous to bzero, bcopy, etc., except that it just reads
- * data into the processor
- */
-long
-bread(void* buf, long nbytes)
-{
-       long sum = 0;
-       register long *p, *next;
-       register char *end;
-
-       p = (long*)buf;
-       end = (char*)buf + nbytes;
-       for (next = p + 128; (void*)next <= (void*)end; p = next, next += 128) {
-               sum +=
-                       p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7]+
-                       p[8]+p[9]+p[10]+p[11]+p[12]+p[13]+p[14]+
-                       p[15]+p[16]+p[17]+p[18]+p[19]+p[20]+p[21]+
-                       p[22]+p[23]+p[24]+p[25]+p[26]+p[27]+p[28]+
-                       p[29]+p[30]+p[31]+p[32]+p[33]+p[34]+p[35]+
-                       p[36]+p[37]+p[38]+p[39]+p[40]+p[41]+p[42]+
-                       p[43]+p[44]+p[45]+p[46]+p[47]+p[48]+p[49]+
-                       p[50]+p[51]+p[52]+p[53]+p[54]+p[55]+p[56]+
-                       p[57]+p[58]+p[59]+p[60]+p[61]+p[62]+p[63]+
-                       p[64]+p[65]+p[66]+p[67]+p[68]+p[69]+p[70]+
-                       p[71]+p[72]+p[73]+p[74]+p[75]+p[76]+p[77]+
-                       p[78]+p[79]+p[80]+p[81]+p[82]+p[83]+p[84]+
-                       p[85]+p[86]+p[87]+p[88]+p[89]+p[90]+p[91]+
-                       p[92]+p[93]+p[94]+p[95]+p[96]+p[97]+p[98]+
-                       p[99]+p[100]+p[101]+p[102]+p[103]+p[104]+
-                       p[105]+p[106]+p[107]+p[108]+p[109]+p[110]+
-                       p[111]+p[112]+p[113]+p[114]+p[115]+p[116]+
-                       p[117]+p[118]+p[119]+p[120]+p[121]+p[122]+
-                       p[123]+p[124]+p[125]+p[126]+p[127];
-       }
-       for (next = p + 16; (void*)next <= (void*)end; p = next, next += 16) {
-               sum +=
-                       p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7]+
-                       p[8]+p[9]+p[10]+p[11]+p[12]+p[13]+p[14]+
-                       p[15];
-       }
-       for (next = p + 1; (void*)next <= (void*)end; p = next, next++) {
-               sum += *p;
-       }
-       return sum;
-}
-
-int
-cp(char* src, char* dst, mode_t mode)
-{
-    int sfd, dfd;
-    char buf[8192];
-    ssize_t size;
-
-    if ((sfd = open(src, O_RDONLY)) < 0) {
-        return -1;
-    }
-    if ((dfd = open(dst, O_CREAT|O_TRUNC|O_RDWR, mode)) < 0) {
-        return -1;
-    }
-    while ((size = read(sfd, buf, 8192)) > 0) {
-        if (write(dfd, buf, size) < size) return -1;
-    }
-    fsync(dfd);
-    close(sfd);
-    close(dfd);
-    return 0;
-}
-
-
-int
-benchmark_init()
-{
-       debug("benchmark_init");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "f:is:");
-       /*
-        *      tsd_t is the state info struct that we pass around 
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "               -f filename\n"
-               "               -s size\n"
-               "               [-i] io_only (no open/close)\n"
-           "notes: read and sum file via memory mapping mmap(2) interface");
-       sprintf(optf, "/tmp/%d", (int)getpid());
-       opts = 1024;
-       return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- * the format was defined in the lm_optstr assignment
- * in benchmark_init
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       debug("benchmark_optswitch");
-       
-       switch (opt) {
-       case 'f':
-               strncpy(optf, optarg, 255);
-               debug("optf = %s\n", optf);
-               break;
-       case 'i':
-               opti = true;
-               debug("opti = %s\n", opti? "true": "false");
-               break;
-       case 's':
-               opts = sizetoint(optarg);
-               debug("opts = %d\n", opts);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       debug("benchmark_initrun");
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t   *state = (tsd_t *)tsd;
-       
-       strncpy(state->filename, optf, 255);
-       state->nbytes = opts;
-       state->open_read_close = opti;
-
-       debug("benchmark_initworker\n");        
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t   *state = (tsd_t *)tsd;
-       state->fd = -1;
-       state->buf = NULL;
-
-       if (state->clone) {
-               char buf[8192];
-               char* s;
-
-               /* copy original file into a process-specific one */
-               sprintf(buf, "/tmp/%d", (int)getpid());
-               s = (char*)malloc(strlen(state->filename) + strlen(buf) + 1);
-               sprintf(s, "/tmp/%s%d", state->filename, (int)getpid());
-               if (cp(state->filename, s, S_IREAD|S_IWRITE) < 0) {
-                       perror("creating private tempfile");
-                       unlink(s);
-                       exit(1);
-               }
-               strcpy(state->filename, s);
-       }
-
-       CHK(state->fd = open(state->filename, 0));
-       CHK(state->buf = mmap(0, state->nbytes, PROT_READ,
-                                    MMAP_FLAGS, state->fd, 0));
-       debug("benchmark_initbatch");
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      try not to initialize things here.  This is the main
-        *  loop of things to get timed.  Start a server in 
-        *  benchmark_initbatch
-        */
-       tsd_t   *state = (tsd_t *)tsd;
-       int             i;
-       int             fd;
-       void    *p;
-       
-       debug("in to benchmark - optB = %i", lm_optB);
-       for (i = 0; i < lm_optB; i++) {
-               if (state->open_read_close) {
-                       CHK(fd = open(state->filename, 0));
-                       CHK(p = mmap(0, state->nbytes, PROT_READ, MMAP_FLAGS, fd, 0));
-                       bread(p, state->nbytes);
-                       close(fd);
-                       munmap(p, state->nbytes);
-               } else {
-                       bread(state->buf, state->nbytes);
-               }
-       }
-       res->re_count = i;
-       debug("out of benchmark - optB = %i", lm_optB);
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t   *state = (tsd_t *)tsd;
-       if (state->buf) munmap(state->buf, state->nbytes);
-       if (state->fd >= 0) close(state->fd);
-       if (state->clone) unlink(state->filename);
-       debug("benchmark_finibatch");
-       return (0);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       debug("benchmark_finiworker");
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       debug("benchmark_result");
-       return (&result);
-}
-
-int
-benchmark_finirun()
-{
-       debug("benchmark_finirun");
-       return (0);
-}
-
-
-int
-benchmark_fini()
-{
-       debug("benchmark_fini");
-       return (0);
-}
-
diff --git a/tools/tests/libMicro/apple/lmbench_bw_unix.c b/tools/tests/libMicro/apple/lmbench_bw_unix.c
deleted file mode 100644 (file)
index 9c86510..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)trivial.c  1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-// add additional headers needed here.
-#include <sys/socket.h>
-#include <signal.h>
-
-#include "../libmicro.h"
-
-void   writer(int controlfd, int writefd, char* buf, void* cookie);
-void   touch(char *buf, int nbytes);
-
-#if DEBUG
-# define debug(fmt, args...)   (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       int     pid;
-       size_t  xfer;   /* bytes to read/write per "packet" */
-       size_t  bytes;  /* bytes to read/write in one iteration */
-       char    *buf;   /* buffer memory space */
-       int     pipes[2];
-       int     control[2];
-       int     initerr;
-       int     parallel;
-       int warmup;
-       int repetitions;
-} tsd_t;
-
-size_t XFER    = 10*1024*1024;
-#ifndef XFERSIZE
-#define XFERSIZE    (64*1024)   /* all bandwidth I/O should use this */
-#endif
-
-/*
- * You can have any lower-case option you want to define.
- * options are specified in the lm_optstr as either a 
- * single lower-case letter, or a single lower case letter 
- * with a colon after it.  In this example, you can optionally
- * specify -c {str} -e or -t {number}  
- *    -c takes a string (quote the string if blanks)
- *    -e is a boolean 
- *    -t takes a numeric
- * argument.
- */
-static int     optm = XFERSIZE;
-static int     opts = 10*1024*1024;
-static int     optw = 0;
-
-int
-benchmark_init()
-{
-       debug("benchmark_init\n");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "m:s:w:");
-       /*
-        *      
-        *      tsd_t is the state_information struct 
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "               [-m <message size>]\n"
-               "               [-s <total bytes>]\n"
-               "               [-w <warmup>]\n");
-       
-       return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- * the format was defined in the lm_optstr assignment
- * in benchmark_init
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       debug("benchmark_optswitch\n");
-       
-       switch (opt) {
-               case 'm':
-                       optm = atoi(optarg);
-                       break;
-               case 's':
-                       opts = atoi(optarg);
-                       break;
-               case 'w':
-                       optw = atoi(optarg);
-                       break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       debug("benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t   *state = (tsd_t *)tsd;
-       state->xfer = optm;
-       state->bytes = opts;
-       state->parallel = lm_optP;
-       state->warmup = optw;
-       state->repetitions = lm_optB;
-       debug("benchmark_initworker: repetitions = %i\n",state->repetitions);   
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t   *state = (tsd_t *)tsd;
-
-       state->buf = valloc(XFERSIZE);
-       touch(state->buf, XFERSIZE);
-       state->initerr = 0;
-       if (socketpair(AF_UNIX, SOCK_STREAM, 0, state->pipes) == -1) {
-               perror("socketpair");
-               state->initerr = 1;
-               return(0);
-       }
-       if (pipe(state->control) == -1) {
-               perror("pipe");
-               state->initerr = 2;
-               return(0);
-       }
-//     handle_scheduler(benchmp_childid(), 0, 1);
-       switch (state->pid = fork()) {
-           case 0:
-//           handle_scheduler(benchmp_childid(), 1, 1);
-               close(state->control[1]);
-               close(state->pipes[0]);
-               writer(state->control[0], state->pipes[1], state->buf, state);
-               return (0);
-               /*NOTREACHED*/
-           
-           case -1:
-               perror("fork");
-               state->initerr = 3;
-               return (0);
-               /*NOTREACHED*/
-
-           default:
-               break;
-       }
-       close(state->control[0]);
-       close(state->pipes[1]);
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      try not to initialize things here.  This is the main
-        *  loop of things to get timed.  Start a server in 
-        *  benchmark_initbatch
-        */
-       tsd_t   *state = (tsd_t *)tsd;
-       size_t  done, n;
-       size_t  todo = state->bytes;
-       int             i;
-       
-       debug("in to benchmark - optB = %i : repetitions = %i\n", lm_optB, state->repetitions);
-       for (i = 0; i < lm_optB; i++) {
-               write(state->control[1], &todo, sizeof(todo));
-               for (done = 0; done < todo; done += n) {
-                       if ((n = read(state->pipes[0], state->buf, state->xfer)) <= 0) {
-                               /* error! */
-                               debug("error (n = %d) exiting now\n", n);
-                               exit(1);
-                       }
-               }
-       }
-       res->re_count = i;
-       debug("out of benchmark - optB = %i : repetitions = %i\n", lm_optB, state->repetitions);
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *state = (tsd_t *)tsd;
-
-       close(state->control[1]);
-       close(state->pipes[0]);
-       if (state->pid > 0) {
-               kill(state->pid, SIGKILL);
-               waitpid(state->pid, NULL, 0);
-       }
-       state->pid = 0;
-       return (0);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       // useless code to show what you can do.
-        ts->repetitions++;
-        ts->repetitions--;
-       debug("benchmark_finiworker: repetitions = %i\n",ts->repetitions);
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       debug("benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finirun()
-{
-       debug("benchmark_finirun\n");
-       return (0);
-}
-
-
-int
-benchmark_fini()
-{
-       debug("benchmark_fini\n");
-       return (0);
-}
-
-/*
- * functions from bw_unix.c
- */
-void
-writer(int controlfd, int writefd, char* buf, void* cookie)
-{
-       size_t  todo, n, done;
-       tsd_t   *state = (tsd_t *)cookie;
-
-       for ( ;; ) {
-               read(controlfd, &todo, sizeof(todo));
-               for (done = 0; done < todo; done += n) {
-#ifdef TOUCH
-                       touch(buf, XFERSIZE);
-#endif
-                       if ((n = write(writefd, buf, state->xfer)) < 0) {
-                               /* error! */
-                               exit(1);
-                       }
-               }
-       }
-}
-
-void
-touch(char *buf, int nbytes)
-{
-    static int psize;
-
-    if (!psize) {
-        psize = getpagesize();
-    }
-    while (nbytes > 0) {
-        *buf = 1;
-        buf += psize;
-        nbytes -= psize;
-    }
-}
-
diff --git a/tools/tests/libMicro/apple/lmbench_fstat.c b/tools/tests/libMicro/apple/lmbench_fstat.c
deleted file mode 100644 (file)
index f417005..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_fstat.c    1.4     06/21/06 Apple Inc."
-#endif
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "../libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-       int                     ts_fd;
-} tsd_t;
-
-
-#define        DEFF                    "/dev/null"
-#define        DEFS                    1024
-
-static char                    *optf = DEFF;
-// static long long            opts = DEFS;
-
-int
-benchmark_init()
-{
-
-       (void) sprintf(lm_optstr, "f:");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-stat (default %s)]\n"
-           "notes: measures lmbench_fstat()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-/*
- * This initbatch stolen from lmbench_read.c
- */
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (ts->ts_buf == NULL) {
-               /* ts->ts_buf = malloc(opts); */
-               ts->ts_fd = open(optf, O_RDONLY);
-       }
-
-       /* (void) lseek(ts->ts_fd, 0, SEEK_SET); */
-
-       return (0);
-}
-
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct stat             sbuf;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       res->re_errors = 0;
-       
-/*
- * The libmicro test uses a for loop as below:
- *   for (i = 0; i < lm_optB; i++) {
- *
- * we can probably get away with using lm_optB
- * in the while loop below
- *
- */
-       i = 0;
-
-//     while (i++ < lm_optB) {
-    for (i = 0; i < lm_optB; i++) {
-               if (fstat(ts->ts_fd, &sbuf) == -1)
-                       res->re_errors++;
-       }
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_lat_ctx.c b/tools/tests/libMicro/apple/lmbench_lat_ctx.c
deleted file mode 100644 (file)
index 2cbe790..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)trivial.c  1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <signal.h>
-#include <strings.h>
-
-#include <sys/sysctl.h>
-#include "../libmicro.h"
-
-#if 1
-# define debug(fmt, args...)   (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-#define        MAXPROC 2048
-#define        CHUNK   (4<<10)
-#define        TRIPS   5
-#ifndef        max
-#define        max(a, b)       ((a) > (b) ? (a) : (b))
-#endif
-
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       int     process_size;
-       double  overhead;
-       int     procs;
-       pid_t*  pids;
-       int     **p;
-       void*   data;
-} tsd_t;
-
-static int     opts = 1;
-
-void   doit(int rd, int wr, int process_size);
-int            create_pipes(int **p, int procs);
-int            create_daemons(int **p, pid_t *pids, int procs, int process_size);
-void   initialize_overhead(void* tsd);
-void   cleanup_overhead(void* tsd);
-void   benchmark_overhead(void* tsd);
-void   initialize(void* tsd);
-void   cleanup(void* tsd);
-long   bread(void* buf, long nbytes);
-
-
-#pragma mark *** lmbench routines
-
-/*
- * lmbench routines, etc. brought over for this benchmark
- */
-void
-morefds(void)
-{
-#ifdef  RLIMIT_NOFILE
-        struct  rlimit r;
-
-        getrlimit(RLIMIT_NOFILE, &r);
-        r.rlim_cur = r.rlim_max;
-        setrlimit(RLIMIT_NOFILE, &r);
-#endif
-}
-
-void
-doit(int rd, int wr, int process_size)
-{
-       int     msg;
-       void*   data = NULL;
-
-       if (process_size) {
-               data = malloc(process_size);
-               if (data) bzero(data, process_size);
-       }
-       for ( ;; ) {
-               if (read(rd, &msg, sizeof(msg)) != sizeof(msg)) {
-                       debug("read/write on pipe"); 
-                       break;
-               }
-               bread(data, process_size);
-               if (write(wr, &msg, sizeof(msg)) != sizeof(msg)) {
-                       debug("read/write on pipe");
-                       break;
-               }
-       }
-       exit(0);
-}
-
-/*
- * Return the number of processors in this host
- */
-int
-sched_ncpus()
-{
-#ifdef MP_NPROCS
-       /* SGI IRIX interface */
-       return sysmp(MP_NPROCS);
-#elif defined(HAVE_MPCTL)
-       /* HP-UX interface */
-       return mpctl(MPC_GETNUMSPUS_SYS, 0, 0);
-#elif defined(_SC_NPROCESSORS_ONLN)
-       /* AIX, Solaris, and Linux interface */
-       return sysconf(_SC_NPROCESSORS_ONLN);
-#elif __APPLE__
-       char *name="hw.activecpu";
-       int cpus, retval;       
-       size_t len = 4;
-       retval=sysctlbyname(name, &cpus, &len, NULL, 0);
-       /* Check retval here */ 
-       debug("cpus = %d retval = %d", cpus, retval);
-       return cpus;
-#endif
-       return 1;
-}
-
-/*
- * Use to get sequentially created processes "far" away from
- * each other in an SMP.
- *
- * XXX: probably doesn't work for NCPUS not a power of two.
- */
-int
-reverse_bits(int cpu)
-{
-       int     i;
-       int     nbits;
-       int     max = sched_ncpus() - 1;
-       int     cpu_reverse = 0;
-
-       for (i = max>>1, nbits = 1; i > 0; i >>= 1, nbits++)
-         ;
-       /* now reverse the bits */
-       for (i = 0; i < nbits; i++) {
-               if (cpu & (1<<i))
-                       cpu_reverse |= (1<<(nbits-i-1));
-       }
-       return cpu_reverse;
-}
-
-
-/*
- * The interface used by benchmp.
- *
- * childno is the "logical" child id number.  
- *     In range [0, ..., parallel-1].
- * benchproc is the "logical" id within the benchmark process.  The
- *     benchmp-created process is logical ID zero, child processes
- *     created by the benchmark range from [1, ..., nbenchprocs].
- * nbenchprocs is the number of child processes that each benchmark
- *     process will create.  Most benchmarks will leave this zero,
- *     but some such as the pipe() benchmarks will not.
- */
-int
-handle_scheduler(int childno, int benchproc, int nbenchprocs)
-{
-       int     cpu = 0;
-       char*   sched = getenv("LMBENCH_SCHED");
-       
-       if (!sched || strcasecmp(sched, "DEFAULT") == 0) {
-               /* do nothing.  Allow scheduler to control placement */
-               return 0;
-       } else if (strcasecmp(sched, "SINGLE") == 0) {
-               /* assign all processes to CPU 0 */
-               cpu = 0;
-       } else if (strcasecmp(sched, "BALANCED") == 0) {
-               /* assign each benchmark process to its own processor,
-                * but child processes will share the CPU with the
-                * parent.
-                */
-               cpu = childno;
-       } else if (strcasecmp(sched, "BALANCED_SPREAD") == 0) {
-               /* 
-                * assign each benchmark process to its own processor, 
-                * logically as far away from neighboring IDs as 
-                * possible.  This can help identify bus contention
-                * issues in SMPs with hierarchical busses or NUMA
-                * memory.
-                */
-               cpu = reverse_bits(childno);
-       } else if (strcasecmp(sched, "UNIQUE") == 0) {
-               /*
-                * assign each benchmark process and each child process
-                * to its own processor.
-                */
-               cpu = childno * (nbenchprocs + 1) + benchproc;
-       } else if (strcasecmp(sched, "UNIQUE_SPREAD") == 0) {
-               /* 
-                * assign each benchmark process and each child process
-                * to its own processor, logically as far away from 
-                * neighboring IDs as possible.  This can help identify 
-                * bus contention issues in SMPs with hierarchical busses
-                * or NUMA memory.
-                */
-               cpu = reverse_bits(childno * (nbenchprocs + 1) + benchproc);
-       } 
-#if 0 // BLOB
-         else if (strncasecmp(sched, "CUSTOM ", strlen("CUSTOM ")) == 0) {
-               cpu = custom(sched + strlen("CUSTOM"), childno);
-       } else if (strncasecmp(sched, "CUSTOM_UNIQUE ", strlen("CUSTOM_UNIQUE ")) == 0) {
-               cpu = custom(sched + strlen("CUSTOM_UNIQUE"), 
-                            childno * (nbenchprocs + 1) + benchproc);
-       } 
-#endif // BLOB
-               else {
-               /* default action: do nothing */
-               return 0;
-       }
-       debug("cpu = %d, sched_ncpus() = %d", cpu, sched_ncpus());
-       return 0;
-//     return sched_pin(cpu % sched_ncpus());
-}
-
-int
-create_daemons(int **p, pid_t *pids, int procs, int process_size)
-{
-       int     i, j;
-       int     msg;
-
-       /*
-        * Use the pipes as a ring, and fork off a bunch of processes
-        * to pass the byte through their part of the ring.
-        *
-        * Do the sum in each process and get that time before moving on.
-        */
-       handle_scheduler(getpid(), 0, procs-1);
-       for (i = 1; i < procs; ++i) {
-               switch (pids[i] = fork()) {
-                   case -1:    /* could not fork, out of processes? */
-                       return i;
-
-                   case 0:     /* child */
-                       handle_scheduler(getpid(), i, procs-1);
-                       for (j = 0; j < procs; ++j) {
-                               if (j != i - 1) close(p[j][0]);
-                               if (j != i) close(p[j][1]);
-                       }
-                       doit(p[i-1][0], p[i][1], process_size);
-                       /* NOTREACHED */
-
-                   default:    /* parent */
-                       ;
-               }
-       }
-
-       /*
-        * Go once around the loop to make sure that everyone is ready and
-        * to get the token in the pipeline.
-        */
-       if (write(p[0][1], &msg, sizeof(msg)) != sizeof(msg) ||
-           read(p[procs-1][0], &msg, sizeof(msg)) != sizeof(msg)) {
-               debug("write/read/write on pipe"); 
-               exit(1);
-       }
-       return procs;
-}
-
-int
-create_pipes(int **p, int procs)
-{
-       int     i;
-       /*
-        * Get a bunch of pipes.
-        */
-       morefds();
-       for (i = 0; i < procs; ++i) {
-               if (pipe(p[i]) == -1) {
-                       return i;
-               }
-       }
-       return procs;
-}
-
-void
-initialize_overhead(void* cookie)
-{
-    int i;
-    int procs;
-    int* p;
-    tsd_t      *pState = (tsd_t *)cookie;
-
-    pState->pids = NULL;
-    pState->p = (int**)malloc(pState->procs * (sizeof(int*) + 2 * sizeof(int)));
-    p = (int*)&pState->p[pState->procs];
-    for (i = 0; i < pState->procs; ++i) {
-        pState->p[i] = p;
-        p += 2;
-    }
-
-    pState->data = (pState->process_size > 0) ? malloc(pState->process_size) : NULL;
-    if (pState->data)
-        bzero(pState->data, pState->process_size);
-
-    procs = create_pipes(pState->p, pState->procs);
-    if (procs < pState->procs) {
-       debug("procs < pState->procs");
-        cleanup_overhead(cookie);
-        exit(1);
-    }
-}
-
-void
-cleanup_overhead(void* tsd)
-{
-       int     i;
-       tsd_t   *ts = (tsd_t *)tsd;
-
-       for (i = 0; i < ts->procs; ++i) {
-               close(ts->p[i][0]);
-               close(ts->p[i][1]);
-       }
-
-       free(ts->p);
-       if (ts->data) free(ts->data);
-}
-
-void
-cleanup(void* cookie)
-{
-    int        i;
-    tsd_t      *pState = (tsd_t *)cookie;
-
-
-    /*
-     * Close the pipes and kill the children.
-     */
-    cleanup_overhead(cookie);
-        for (i = 1; pState->pids && i < pState->procs; ++i) {
-        if (pState->pids[i] > 0) {
-            kill(pState->pids[i], SIGKILL);
-            waitpid(pState->pids[i], NULL, 0);
-        }
-    }
-    if (pState->pids)
-        free(pState->pids);
-    pState->pids = NULL;
-}
-
-void
-benchmark_overhead(void* tsd)
-{
-       tsd_t   *ts = (tsd_t *)tsd;
-       int     i = 0;
-       int     msg = 1;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (write(ts->p[i][1], &msg, sizeof(msg)) != sizeof(msg)) {
-                       debug("read/write on pipe");
-                       exit(1);                                
-               }
-               if (read(ts->p[i][0], &msg, sizeof(msg)) != sizeof(msg)) {
-                       debug("read/write on pipe");
-                       exit(1);
-               }
-               if (++i == ts->procs) {
-                       i = 0;
-               }
-               bread(ts->data, ts->process_size);
-       }
-}
-
-/* analogous to bzero, bcopy, etc., except that it just reads
- * data into the processor
- */
-long
-bread(void* buf, long nbytes)
-{
-       long sum = 0;
-       register long *p, *next;
-       register char *end;
-
-       p = (long*)buf;
-       end = (char*)buf + nbytes;
-       for (next = p + 128; (void*)next <= (void*)end; p = next, next += 128) {
-               sum +=
-                       p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7]+
-                       p[8]+p[9]+p[10]+p[11]+p[12]+p[13]+p[14]+
-                       p[15]+p[16]+p[17]+p[18]+p[19]+p[20]+p[21]+
-                       p[22]+p[23]+p[24]+p[25]+p[26]+p[27]+p[28]+
-                       p[29]+p[30]+p[31]+p[32]+p[33]+p[34]+p[35]+
-                       p[36]+p[37]+p[38]+p[39]+p[40]+p[41]+p[42]+
-                       p[43]+p[44]+p[45]+p[46]+p[47]+p[48]+p[49]+
-                       p[50]+p[51]+p[52]+p[53]+p[54]+p[55]+p[56]+
-                       p[57]+p[58]+p[59]+p[60]+p[61]+p[62]+p[63]+
-                       p[64]+p[65]+p[66]+p[67]+p[68]+p[69]+p[70]+
-                       p[71]+p[72]+p[73]+p[74]+p[75]+p[76]+p[77]+
-                       p[78]+p[79]+p[80]+p[81]+p[82]+p[83]+p[84]+
-                       p[85]+p[86]+p[87]+p[88]+p[89]+p[90]+p[91]+
-                       p[92]+p[93]+p[94]+p[95]+p[96]+p[97]+p[98]+
-                       p[99]+p[100]+p[101]+p[102]+p[103]+p[104]+
-                       p[105]+p[106]+p[107]+p[108]+p[109]+p[110]+
-                       p[111]+p[112]+p[113]+p[114]+p[115]+p[116]+
-                       p[117]+p[118]+p[119]+p[120]+p[121]+p[122]+
-                       p[123]+p[124]+p[125]+p[126]+p[127];
-       }
-       for (next = p + 16; (void*)next <= (void*)end; p = next, next += 16) {
-               sum +=
-                       p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7]+
-                       p[8]+p[9]+p[10]+p[11]+p[12]+p[13]+p[14]+
-                       p[15];
-       }
-       for (next = p + 1; (void*)next <= (void*)end; p = next, next++) {
-               sum += *p;
-       }
-       return sum;
-}
-
-#pragma mark *** darbench routines
-
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int procs;
-
-       initialize_overhead(tsd);
-
-       ts->pids = (pid_t*)malloc(ts->procs * sizeof(pid_t));
-       if (ts->pids == NULL)
-               exit(1);
-       bzero((void*)ts->pids, ts->procs * sizeof(pid_t));
-       procs = create_daemons(ts->p, ts->pids, 
-                              ts->procs, ts->process_size);
-       if (procs < ts->procs) {
-               cleanup(tsd);
-               exit(1);
-       }
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "s:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "               [-s kbytes]\n"
-               "               processes [processes ...]\n");
-
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int i;
-       
-       /*
-        * Close the pipes and kill the children.
-        */
-       cleanup_overhead(tsd);
-       for (i = 1; ts->pids && i < ts->procs; ++i) {
-               if (ts->pids[i] > 0) {
-                       kill(ts->pids[i], SIGKILL);
-                       waitpid(ts->pids[i], NULL, 0);
-               }
-       }
-       if (ts->pids)
-               free(ts->pids);
-       ts->pids = NULL;
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       
-       switch (opt) {
-       case 's':
-               opts = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t           *ts = (tsd_t *)tsd;
-       
-       ts->process_size = opts;
-        
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       tsd_t           *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     msg=1;
-       
-       for (i = 0; i < lm_optB; i++) {
-               if (write(ts->p[0][1], &msg, sizeof(msg)) !=
-                   sizeof(msg)) {
-                       debug("read/write on pipe");
-                       exit(1);
-               }
-               if (read(ts->p[ts->procs-1][0], &msg, sizeof(msg)) != sizeof(msg)) {
-                       debug("read/write on pipe");
-                       exit(1);
-               }
-               bread(ts->data, ts->process_size);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_lat_sig_catch.c b/tools/tests/libMicro/apple/lmbench_lat_sig_catch.c
deleted file mode 100644 (file)
index edca677..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_lat_sig_catch.c    1.0     08/16/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-static int optp = 1;
-static int optw = 0;
-static int optn = -1;
-
-u_int64_t      caught, n;
-double adj;
-void   handler(int s) { }
-jmp_buf        prot_env;
-
-typedef struct {
-        int     pid;
-} tsd_t;
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "p:w:n");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-p <parallelism>]\n"           
-           "       [-w <warmup>]\n"
-           "       [-n <repetitions>]\n"
-           "notes: measures lmbench lat_sig install\n");
-       lm_defB = 1;
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       /* 
-        *      more proof of state passing
-        */
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       
-       switch (opt) {
-       case 'w':
-               optw = sizetoint(optarg);
-               break;
-       case 'n':
-               optn = sizetoint(optarg);
-               break;
-       case 'p':
-               optp = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t* ts = (tsd_t*)tsd;
-       struct  sigaction sa, old;
-       
-       sa.sa_handler = handler;
-       (void) sigemptyset(&sa.sa_mask);        
-       sa.sa_flags = 0;
-       (void) sigaction(SIGUSR1, &sa, &old);
-
-    ts->pid = getpid();
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       int i;
-       tsd_t* ts = (tsd_t*)tsd;
-       
-       for (i = 0; i < lm_optB; i++) {
-               (void) kill(ts->pid, SIGUSR1);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_lat_sig_install.c b/tools/tests/libMicro/apple/lmbench_lat_sig_install.c
deleted file mode 100644 (file)
index ee1acd6..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_lat_sig_install.c  1.0     08/16/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-static int optp = 1;
-static int optw = 0;
-static int optn = -1;
-
-u_int64_t      caught, n;
-double adj;
-void   handler(int s) { }
-jmp_buf        prot_env;
-
-typedef struct {
-        int     ts_once;
-} tsd_t;
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "t:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-p <parallelism>]\n"           
-           "       [-w <warmup>]\n"
-           "       [-n <repetitions>]\n"
-           "notes: measures lmbench lat_sig install\n");
-       lm_defB = 1;   
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       /* 
-        *      more proof of state passing
-        */
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       
-       switch (opt) {
-       case 'w':
-               optw = sizetoint(optarg);
-               break;
-       case 'n':
-               optn = sizetoint(optarg);
-               break;
-       case 'p':
-               optp = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       struct  sigaction sa, old;
-       int i;
-       
-       for (i = 0; i < lm_optB; i++) {
-               sa.sa_handler = handler;
-               sigemptyset(&sa.sa_mask);       
-               sa.sa_flags = 0;
-               sigaction(SIGUSR1, &sa, &old);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_lat_sig_prot.c b/tools/tests/libMicro/apple/lmbench_lat_sig_prot.c
deleted file mode 100644 (file)
index b2612e9..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_lat_sig_prot.c     1.0     08/16/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <string.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <errno.h>
-
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-static int optp = 1;
-static int optw = 0;
-static int optn = -1;
-static char    *optf = "/Volumes/data/darbench/bin-i386/lmbench_lat_sig_prot";
-static int *mappedfile;
-jmp_buf jumper;
-
-u_int64_t      caught, n;
-double adj;
-void   handler(int s) { }
-jmp_buf        prot_env;
-
-typedef struct {
-       char*   fname;
-       char*   where;
-} tsd_t;
-
-
-void
-prot(int s)
-{
-       _longjmp(jumper, s);
-
-}
-
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       (void) fprintf(stderr, "benchmark_initbatch: entry\n");
-
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "p:w:n:f");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-p <parallelism>]\n"           
-           "       [-w <warmup>]\n"
-           "       [-n <repetitions>]\n"
-           "       [-f <filename>]\n"
-           "notes: measures lmbench lat_sig prot\n");
-       (void) fprintf(stderr, "benchmark_init: entry\n");
-       lm_defB = 1;
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       /* 
-        *      more proof of state passing
-        */
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       (void) fprintf(stderr, "benchmark_optswitch: entry\n");
-
-       switch (opt) {
-       case 'w':
-               optw = sizetoint(optarg);
-               break;
-       case 'n':
-               optn = sizetoint(optarg);
-               break;
-       case 'p':
-               optp = sizetoint(optarg);
-               break;
-       case 'f':
-               (void) fprintf(stderr, "benchmark_optswitch: FILENAME entry = %s\n",optf);
-               //strcpy(optf, optarg);
-               (void) fprintf(stderr, "benchmark_optswitch: FILENAME exit\n");
-               break;
-       default:
-               return (-1);
-       }
-       (void) fprintf(stderr, "benchmark_optswitch: exit\n");
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t* ts = (tsd_t*)tsd;
-       int fd;
-       struct  sigaction sa;
-       (void) fprintf(stderr, "benchmark_initworker: entry = %s\n",optf);
-
-    ts->fname = optf;
-    fd = open(ts->fname, 0);
-    (void) fprintf(stderr, "benchmark_initworker: open result is %i\n",fd);
-       (void) fprintf(stderr, "benchmark_initworker: errno result is %d - \"%s\"\n",errno, strerror(errno));
-
-    ts->where = mmap(0,4096, PROT_READ, MAP_SHARED, fd, 0);
-    (void) fprintf(stderr, "benchmark_initworker: mmap result is %i\n",ts->where);
-       *mappedfile = (int) ts->where;
-       (void) fprintf(stderr, "benchmark_initworker: mappedfile result is %i\n",*mappedfile);
-
-    if ((long)ts->where == -1) {
-       perror("mmap");
-       exit(1);
-    }
-    
-    sa.sa_handler = prot;
-       sigemptyset(&sa.sa_mask);
-       sa.sa_flags = 0;
-       sigaction(SIGSEGV, &sa, 0);
-       sigaction(SIGBUS, &sa, 0);
-       
-
-    caught = 0;
-    n = lm_optB;
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) fprintf(stderr, "benchmark_initrun: entry\n");
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       int i;
-       //tsd_t* ts = (tsd_t*)tsd;
-       (void) fprintf(stderr, "benchmark: lm_optB = %i\n",lm_optB);
-       for (i = 0; i < lm_optB; i++) {
-               if (_setjmp(jumper) == 0) {
-                       
-                       *mappedfile= 1;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_lat_sig_send.c b/tools/tests/libMicro/apple/lmbench_lat_sig_send.c
deleted file mode 100644 (file)
index 9797bc4..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_lat_sig_catch.c    1.0     08/16/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-static int optp = 1;
-static int optw = 0;
-static int optn = -1;
-
-u_int64_t      caught, n;
-double adj;
-void   handler(int s) { }
-jmp_buf        prot_env;
-
-typedef struct {
-        int     pid;
-} tsd_t;
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "p:w:n");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-p <parallelism>]\n"           
-           "       [-w <warmup>]\n"
-           "       [-n <repetitions>]\n"
-           "notes: measures lmbench lat_sig install\n");
-       lm_defB = 1;
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       /* 
-        *      more proof of state passing
-        */
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       
-       switch (opt) {
-       case 'w':
-               optw = sizetoint(optarg);
-               break;
-       case 'n':
-               optn = sizetoint(optarg);
-               break;
-       case 'p':
-               optp = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t* ts = (tsd_t*)tsd;
-    ts->pid = getpid();
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       int i;
-       tsd_t* ts = (tsd_t*)tsd;
-       
-       for (i = 0; i < lm_optB; i++) {
-               (void) kill(ts->pid, 0);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_openclose.c b/tools/tests/libMicro/apple/lmbench_openclose.c
deleted file mode 100644 (file)
index f25154c..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_openclose.c        1.4     06/21/06 Apple Inc."
-#endif
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "../libmicro.h"
-
-#define        DEFF                    "/dev/null"
-static char                    *optf = DEFF;
-
-int
-benchmark_init()
-{
-
-       (void) sprintf(lm_optstr, "f:");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-stat (default %s)]\n"
-           "notes: measures stat()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       int                     fd;
-
-       res->re_errors = 0;
-       
-/*
- * The libmicro test uses a for loop as below:
- *   for (i = 0; i < lm_optB; i++) {
- *
- * we can probably get away with using lm_optB
- * in the while loop below
- *
- */
-       i = 0;
-
-       while (i++ < lm_optB) {
-               fd = open(optf, 0);
-               if (fd == -1) {
-                       res->re_errors++;
-               }
-               close(fd);
-       }
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_read.c b/tools/tests/libMicro/apple/lmbench_read.c
deleted file mode 100644 (file)
index 15225dd..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_read.c     1.5     05/08/04 Apple Inc."
-#endif
-
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "../libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-       int                     ts_fd;
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFS                    1024
-
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-int                            optw = 0;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:s:w");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-read (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-w (store a byte to each page after read)]\n"
-           "notes: measures lmbench_read()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       lm_defB = 1;
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'w':
-               optw = getpagesize();
-               break;
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (ts->ts_buf == NULL) {
-               ts->ts_buf = malloc(opts);
-               ts->ts_fd = open(optf, O_RDONLY);
-       }
-
-       (void) lseek(ts->ts_fd, 0, SEEK_SET);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     j;
-/*
- * The libmicro test uses a for loop as below:
- *   for (i = 0; i < lm_optB; i++) {
- *
- * we can probably get away with using lm_optB
- * in the while loop below
- *
- */
-       i = 0;
-       
-       while (i++ < lm_optB) {
-               if (read(ts->ts_fd, ts->ts_buf, opts) != opts) {
-                       res->re_errors++;
-               }
-               if (optw)
-                       for (j = 0; j < opts; j += optw)
-                               ts->ts_buf[j] = 0;
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_select_file.c b/tools/tests/libMicro/apple/lmbench_select_file.c
deleted file mode 100644 (file)
index cdad43e..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)socket.c   1.3     05/08/04 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-#include "../libmicro.h"
-
-/*
- * lmbench routines, etc. brought over for this benchmark
- */
-int  open_file(void* tsd);
-void server(void* tsd);
-
-
-typedef int (*open_f)(void* tsd);
-/*
- * end of lmbench support routines
- */
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       char    fname[L_tmpnam];
-       open_f  fid_f;
-       pid_t   pid;
-       int     sock;
-       int     fid;
-       int     num;
-       int     max;
-       fd_set  set;
-} tsd_t;
-
-static int     optt = 1;
-static int     optn = -1;
-static int     optp = 1;
-static int     optw = 0;
-
-/*
- * lmbench routines, etc. brought over for this benchmark
- */
-void
-morefds(void)
-{
-#ifdef  RLIMIT_NOFILE
-        struct  rlimit r;
-
-        getrlimit(RLIMIT_NOFILE, &r);
-        r.rlim_cur = r.rlim_max;
-        setrlimit(RLIMIT_NOFILE, &r);
-#endif
-}
-
-int
-open_file(void* tsd)
-{
-       tsd_t* ts = (tsd_t*)tsd;
-       //(void) fprintf(stderr, "open_file: ts->fname = %s\n",ts->fname);
-       return (int) open(ts->fname, O_RDONLY);
-}
-
-void
-server(void* tsd)
-{
-       int pid;
-       tsd_t* ts = (tsd_t*)tsd;
-
-       pid = getpid();
-       ts->pid = 0;
-       //(void) fprintf(stderr, "server: state->fid_f = %i\n",ts->fid_f);
-       
-       if (ts->fid_f == open_file) {
-               /* Create a temporary file for clients to open */
-               sprintf(ts->fname, "/tmp/lat_selectXXXXXX");
-               //(void) fprintf(stderr, "server: ts->fname = %s\n",ts->fname);
-               ts->fid = mkstemp(ts->fname);
-               //(void) fprintf(stderr, "server: ts->fname = %s: ts->fid = %d\n",ts->fname, ts->fid);
-
-               if (ts->fid <= 0) {
-                       char buf[L_tmpnam+128];
-                       sprintf(buf, "lat_select: Could not create temp file %s", ts->fname);
-                       perror(buf);
-                       exit(1);
-               }
-               close(ts->fid);
-               return;
-       }
-//
-//     this is all for the tcp version of this test only
-//
-//     /* Create a socket for clients to connect to */
-//     state->sock = tcp_server(TCP_SELECT, SOCKOPT_REUSE);
-//     if (state->sock <= 0) {
-//             perror("lat_select: Could not open tcp server socket");
-//             exit(1);
-//     }
-
-       /* Start a server process to accept client connections */
-//     switch(state->pid = fork()) {
-//     case 0:
-//             /* child server process */
-//             while (pid == getppid()) {
-//                     int newsock = tcp_accept(state->sock, SOCKOPT_NONE);
-//                     read(newsock, &state->fid, 1);
-//                     close(newsock);
-//             }
-//             exit(0);
-//     case -1:
-//             /* error */
-//             perror("lat_select::server(): fork() failed");
-//             exit(1);
-//     default:
-//             break;
-//     }
-}
-
-
-/*
- * end of lmbench support routines
- */
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       //(void) fprintf(stderr, "benchmark_finirun\n");
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       //(void) fprintf(stderr, "benchmark_init\n");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "p:w:n:t:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "       [-p parallelism (default 1)]\n"                 
-               "       [-w warmup (default 0)]\n"
-               "       [-n number of descriptors (default 1)]\n"
-           "       [-t int (default 1)]\n"
-           "notes: measures lmbench_select_file\n");
-       lm_defB = 1;
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       //(void) fprintf(stderr, "benchmark_fini\n");
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       //(void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int i;
-       // pulls in the lmbench cleanup code
-       //(void) fprintf(stderr, "benchmark_finiworker\n");
-       for (i = 0; i <= ts->max; ++i) {
-               if (FD_ISSET(i, &(ts->set)))
-                       close(i);
-       }
-       FD_ZERO(&(ts->set));
-       unlink(ts->fname);
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       //(void) fprintf(stderr, "benchmark_optswitch\n");
-       
-       switch (opt) {
-       case 't':
-               optt = sizetoint(optarg);
-               break;
-       case 'n':
-               optn = sizetoint(optarg);
-               break;
-       case 'p':
-               optp = sizetoint(optarg);
-               break;
-       case 'w':
-               optw = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{      
-       // pulls in code from lmbench main and initialize
-       int             n = 0;
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int     N, fid, fd;
-       
-       /*
-        * default number of file descriptors
-        */
-       //(void) fprintf(stderr, "benchmark_initworker\n");
-       ts->num = 200;
-       if (optn > 0) {
-               ts->num = optn;
-       }
-       N = ts->num;
-       //(void) fprintf(stderr, "benchmark_initworker ts->num is %i\n",ts->num);
-       
-       /*
-        *      grab more file descriptors
-        */
-        
-       morefds();
-       
-       ts->fid_f = open_file;
-       server(ts);
-       //(void) fprintf(stderr, "benchmark_initworker: returned from server call\n");
-       /* 
-        * Initialize function from lmbench
-        * for this test
-        */
-       fid = (*ts->fid_f)(ts);
-       //(void) fprintf(stderr, "initworker: fid is %i\n",fid);
-       if (fid <= 0) {
-               perror("Could not open device");
-               exit(1);
-       }
-       ts->max = 0;
-       FD_ZERO(&(ts->set));
-       //(void) fprintf(stderr, "initworker FD_ZERO: ts->set result is %i\n",ts->set);
-       //(void) fprintf(stderr, "initworker: N is %i\n",N);
-       for (n = 0; n < N; n++) {
-               //(void) fprintf(stderr, "benchmark_initworker: in the loop - N is %i: n is %i\n",N, n);
-               fd = dup(fid);
-               //(void) fprintf(stderr, "benchmark_initworker: dup result is %i\n",fd);
-               //(void) fprintf(stderr, "benchmark_initworker: errno result is %d - \"%s\"\n",errno, strerror(errno));
-
-               if (fd == -1) break;
-               if (fd > ts->max)
-                       ts->max = fd;
-               FD_SET(fd, &(ts->set));
-               //(void) fprintf(stderr, "initworker FD_SET: ts->set result is %i\n",ts->set);
-
-       }
-       //(void) fprintf(stderr, "benchmark_initworker: after second macro/loop\n");
-
-       ts->max++;
-       close(fid);
-       //(void) fprintf(stderr, "benchmark_initworker: N is %i: n is %i\n",N, n);
-       if (n != N)
-               exit(1);
-       /* end of initialize function */
-       //(void) fprintf(stderr, "benchmark_initworker: about to exit\n");
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       //(void) fprintf(stderr, "benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       fd_set          nosave;
-       static struct timeval tv;
-
-       //(void) fprintf(stderr, "benchmark\n");
-
-       int                     i;
-       //int           sel_res;
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-
-       
-       for (i = 0; i < lm_optB; i++) {
-                nosave = ts->set;
-                //(void) fprintf(stderr, "benchmark: nosave is %i\n", nosave);
-
-                select(ts->num, 0, &nosave, 0, &tv);
-                //(void) fprintf(stderr, "benchmark: select result is %i\n",sel_res);
-                //(void) fprintf(stderr, "benchmark: errno result is %d - \"%s\"\n",errno, strerror(errno));
-
-                
-       }
-       res->re_count = i;
-       return (0);
-}
-
diff --git a/tools/tests/libMicro/apple/lmbench_select_tcp.c b/tools/tests/libMicro/apple/lmbench_select_tcp.c
deleted file mode 100644 (file)
index aea77da..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)socket.c   1.3     05/08/04 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-#include <netinet/in.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#include <netdb.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h>
-
-#include "../libmicro.h"
-
-/*
- * lmbench routines, etc. brought over for this benchmark
- */
-int    open_file(void* tsd);
-void   server(void* tsd);
-int            tcp_accept(int sock, int rdwr);
-void   sock_optimize(int sock, int flags);
-int            sockport(int s);
-int            tcp_server(int prog, int rdwr);
-int            tcp_connect(char *host, int prog, int rdwr);
-int            open_socket(void *tsd);
-
-
-typedef int (*open_f)(void* tsd);
-/*
- * end of lmbench support routines
- */
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-       char    fname[L_tmpnam];
-       open_f  fid_f;
-       pid_t   pid;
-       int     sock;
-       int     fid;
-       int     num;
-       int     max;
-       fd_set  set;
-} tsd_t;
-
-static int     optt = 1;
-static int     optn = -1;
-static int     optp = 1;
-static int     optw = 0;
-
-/*
- * lmbench routines, etc. brought over for this benchmark
- */
-void
-morefds(void)
-{
-#ifdef  RLIMIT_NOFILE
-        struct  rlimit r;
-
-        getrlimit(RLIMIT_NOFILE, &r);
-        r.rlim_cur = r.rlim_max;
-        setrlimit(RLIMIT_NOFILE, &r);
-#endif
-}
-
-int
-open_file(void* tsd)
-{
-       tsd_t* ts = (tsd_t*)tsd;
-               return (int) open(ts->fname, O_RDONLY);
-}
-
-int
-open_socket(void* tsd)
-{
-       return tcp_connect("localhost", TCP_SELECT, SOCKOPT_NONE);
-}
-
-void
-server(void* tsd)
-{
-       int pid;
-       tsd_t           *ts = (tsd_t *)tsd;
-
-       pid = getpid();
-       ts->pid = 0;
-
-       if (ts->fid_f == open_file) {
-               /* Create a temporary file for clients to open */
-               sprintf(ts->fname, "lat_selectXXXXXX");
-               ts->fid = mkstemp(ts->fname);
-               if (ts->fid <= 0) {
-                       char buf[L_tmpnam+128];
-                       sprintf(buf, "lat_select: Could not create temp file %s", ts->fname);
-                       perror(buf);
-                       exit(1);
-               }
-               close(ts->fid);
-               return;
-       }
-
-       /* Create a socket for clients to connect to */
-       ts->sock = tcp_server(TCP_SELECT, SOCKOPT_REUSE);
-       if (ts->sock <= 0) {
-               perror("lat_select: Could not open tcp server socket");
-               exit(1);
-       }
-
-       /* Start a server process to accept client connections */
-       switch(ts->pid = fork()) {
-       case 0:
-               /* child server process */
-               while (pid == getppid()) {
-                       int newsock = tcp_accept(ts->sock, SOCKOPT_NONE);
-                       read(newsock, &ts->fid, 1);
-                       close(newsock);
-               }
-               exit(0);
-       case -1:
-               /* error */
-               perror("lat_select::server(): fork() failed");
-               exit(1);
-       default:
-               break;
-       }
-}
-
-
-/*
- * Accept a connection and return it
- */
-int
-tcp_accept(int sock, int rdwr)
-{
-    struct sockaddr_in         s;
-    int                                newsock;
-    socklen_t                  namelen;
-
-    namelen = sizeof(s);
-    bzero((void*)&s, namelen);
-
-retry:
-    if ((newsock = accept(sock, (struct sockaddr*)&s, &namelen)) < 0) {
-        if (errno == EINTR)
-            goto retry;
-        perror("accept");
-        exit(6);
-    }
-#ifdef  LIBTCP_VERBOSE
-    fprintf(stderr, "Server newsock port %d\n", sockport(newsock));
-#endif
-    sock_optimize(newsock, rdwr);
-    return (newsock);
-}
-
-void
-sock_optimize(int sock, int flags)
-{
-    if (flags & SOCKOPT_READ) {
-        int sockbuf = SOCKBUF;
-
-        while (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sockbuf,
-            sizeof(int))) {
-            sockbuf >>= 1;
-        }
-#ifdef  LIBTCP_VERBOSE
-        fprintf(stderr, "sockopt %d: RCV: %dK\n", sock, sockbuf>>10);
-#endif
-    }
-    if (flags & SOCKOPT_WRITE) {
-        int sockbuf = SOCKBUF;
-
-        while (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sockbuf,
-            sizeof(int))) {
-            sockbuf >>= 1;
-        }
-#ifdef  LIBTCP_VERBOSE
-        fprintf(stderr, "sockopt %d: SND: %dK\n", sock, sockbuf>>10);
-#endif
-    }
-    if (flags & SOCKOPT_REUSE) {
-        int val = 1;
-        if (setsockopt(sock, SOL_SOCKET,
-            SO_REUSEADDR, &val, sizeof(val)) == -1) {
-            perror("SO_REUSEADDR");
-        }
-    }
-}
-
-int
-sockport(int s)
-{
-       socklen_t       namelen;
-       struct sockaddr_in sin;
-
-       namelen = sizeof(sin);
-       if (getsockname(s, (struct sockaddr *)&sin, &namelen) < 0) {
-               perror("getsockname");
-               return(-1);
-       }
-       return ((int)ntohs(sin.sin_port));
-}
-
-/*
- * Get a TCP socket, bind it, figure out the port,
- * and advertise the port as program "prog".
- *
- * XXX - it would be nice if you could advertise ascii strings.
- */
-int
-tcp_server(int prog, int rdwr)
-{
-       int     sock;
-       struct  sockaddr_in s;
-
-#ifdef LIBTCP_VERBOSE
-       fprintf(stderr, "tcp_server(%u, %u)\n", prog, rdwr);
-#endif
-       if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
-               perror("socket");
-               exit(1);
-       }
-       sock_optimize(sock, rdwr);
-       bzero((void*)&s, sizeof(s));
-       s.sin_family = AF_INET;
-       if (prog < 0) {
-               s.sin_port = htons(-prog);
-       }
-       if (bind(sock, (struct sockaddr*)&s, sizeof(s)) < 0) {
-               perror("bind");
-               exit(2);
-       }
-       if (listen(sock, 100) < 0) {
-               perror("listen");
-               exit(4);
-       }
-       if (prog > 0) {
-#ifdef LIBTCP_VERBOSE
-               fprintf(stderr, "Server port %d\n", sockport(sock));
-#endif
-               (void)pmap_unset((u_long)prog, (u_long)1);
-               if (!pmap_set((u_long)prog, (u_long)1, (u_long)IPPROTO_TCP,
-                   (unsigned short)sockport(sock))) {
-                       perror("pmap_set");
-                       exit(5);
-               }
-       }
-       return (sock);
-}
-
-
-/*
- * Connect to the TCP socket advertised as "prog" on "host" and
- * return the connected socket.
- *
- * Hacked Thu Oct 27 1994 to cache pmap_getport calls.  This saves
- * about 4000 usecs in loopback lat_connect calls.  I suppose we
- * should time gethostbyname() & pmap_getprot(), huh?
- */
-int
-tcp_connect(char *host, int prog, int rdwr)
-{
-       static  struct hostent *h;
-       static  struct sockaddr_in s;
-       static  u_short save_port;
-       static  u_long save_prog;
-       static  char *save_host;
-       int     sock;
-       static  int tries = 0;
-
-       if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
-               perror("socket");
-               exit(1);
-       }
-       if (rdwr & SOCKOPT_PID) {
-               static  unsigned short port;
-               struct sockaddr_in sin;
-
-               if (!port) {
-                       port = (unsigned short)(getpid() << 4);
-                       if (port < 1024) {
-                               port += 1024;
-                       }
-               }
-               do {
-                       port++;
-                       bzero((void*)&sin, sizeof(sin));
-                       sin.sin_family = AF_INET;
-                       sin.sin_port = htons(port);
-               } while (bind(sock, (struct sockaddr*)&sin, sizeof(sin)) == -1);
-       }
-#ifdef LIBTCP_VERBOSE
-       else {
-               struct sockaddr_in sin;
-
-               bzero((void*)&sin, sizeof(sin));
-               sin.sin_family = AF_INET;
-               if (bind(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
-                       perror("bind");
-                       exit(2);
-               }
-       }
-       fprintf(stderr, "Client port %d\n", sockport(sock));
-#endif
-       sock_optimize(sock, rdwr);
-       if (!h || host != save_host || prog != save_prog) {
-               save_host = host;       /* XXX - counting on them not
-                                        * changing it - benchmark only.
-                                        */
-               save_prog = prog;
-               if (!(h = gethostbyname(host))) {
-                       perror(host);
-                       exit(2);
-               }
-               bzero((void *) &s, sizeof(s));
-               s.sin_family = AF_INET;
-               bcopy((void*)h->h_addr, (void *)&s.sin_addr, h->h_length);
-               if (prog > 0) {
-                       save_port = pmap_getport(&s, prog,
-                           (u_long)1, IPPROTO_TCP);
-                       if (!save_port) {
-                               perror("lib TCP: No port found");
-                               exit(3);
-                       }
-#ifdef LIBTCP_VERBOSE
-                       fprintf(stderr, "Server port %d\n", save_port);
-#endif
-                       s.sin_port = htons(save_port);
-               } else {
-                       s.sin_port = htons(-prog);
-               }
-       }
-       if (connect(sock, (struct sockaddr*)&s, sizeof(s)) < 0) {
-               if (errno == ECONNRESET 
-                   || errno == ECONNREFUSED
-                   || errno == EAGAIN) {
-                       close(sock);
-                       if (++tries > 10) return(-1);
-                       return (tcp_connect(host, prog, rdwr));
-               }
-               perror("connect");
-               exit(4);
-       }
-       tries = 0;
-       return (sock);
-}
-
-
-/*
- * end of lmbench support routines
- */
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-               return (0);
-}
-
-int
-benchmark_init()
-{
-               /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "p:w:n:t:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "       [-p parallelism (default 1)]\n"                 
-               "       [-w warmup (default 0)]\n"
-               "       [-n number of descriptors (default 1)]\n"
-           "       [-t int (default 1)]\n"
-           "notes: measures lmbench_select_file\n");
-       lm_defB = 1;
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-               return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-               return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int i;
-       // pulls in the lmbench cleanup code
-               for (i = 0; i <= ts->max; ++i) {
-               if (FD_ISSET(i, &(ts->set)))
-                       close(i);
-       }
-       FD_ZERO(&(ts->set));
-       unlink(ts->fname);
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-               
-       switch (opt) {
-       case 't':
-               optt = sizetoint(optarg);
-               break;
-       case 'n':
-               optn = sizetoint(optarg);
-               break;
-       case 'p':
-               optp = sizetoint(optarg);
-               break;
-       case 'w':
-               optw = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{      
-       // pulls in code from lmbench main and initialize
-       int             n = 0;
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int     N, fid, fd;
-       
-       /*
-        * default number of file descriptors
-        */
-               ts->num = 200;
-       if (optn > 0) {
-               ts->num = optn;
-       }
-       N = ts->num;
-               
-       /*
-        *      grab more file descriptors
-        */
-        
-       morefds();
-       
-       ts->fid_f = open_socket;
-       server(ts);
-               /* 
-        * Initialize function from lmbench
-        * for this test
-        */
-       fid = (*ts->fid_f)(ts);
-               if (fid <= 0) {
-               perror("Could not open device");
-               exit(1);
-       }
-       ts->max = 0;
-       FD_ZERO(&(ts->set));
-                       for (n = 0; n < N; n++) {
-                               fd = dup(fid);
-                               //(void) fprintf(stderr, "benchmark_initworker: errno result is %d - \"%s\"\n",errno, strerror(errno));
-
-               if (fd == -1) break;
-               if (fd > ts->max)
-                       ts->max = fd;
-               FD_SET(fd, &(ts->set));
-               //(void) fprintf(stderr, "initworker FD_SET: ts->set result is %i\n",ts->set);
-
-       }
-       //(void) fprintf(stderr, "benchmark_initworker: after second macro/loop\n");
-
-       ts->max++;
-       close(fid);
-               if (n != N)
-               exit(1);
-       /* end of initialize function */
-               return (0);
-}
-
-int
-benchmark_initrun()
-{
-               return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       fd_set          nosave;
-       static struct timeval tv;
-
-       //(void) fprintf(stderr, "benchmark\n");
-
-       int                     i;
-       //int           sel_res;
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-
-       
-       for (i = 0; i < lm_optB; i++) {
-                nosave = ts->set;
-                //(void) fprintf(stderr, "benchmark: nosave is %i\n", nosave);
-
-                select(ts->num, 0, &nosave, 0, &tv);
-                
-       }
-       res->re_count = i;
-       return (0);
-}
-
diff --git a/tools/tests/libMicro/apple/lmbench_stat.c b/tools/tests/libMicro/apple/lmbench_stat.c
deleted file mode 100644 (file)
index b20b025..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-/*
- * Portions Copyright (c) 2006, Apple Inc.
- */
-
-#ifdef __sun
-#pragma ident  "@(#)lmbench_stat.c     1.4     06/21/06 Apple Inc."
-#endif
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "../libmicro.h"
-
-#define        DEFF                    "/dev/null"
-static char                    *optf = DEFF;
-
-int
-benchmark_init()
-{
-
-       (void) sprintf(lm_optstr, "f:");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-stat (default %s)]\n"
-           "notes: measures stat()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct stat             sbuf;
-
-       res->re_errors = 0;
-       
-/*
- * The libmicro test uses a for loop as below:
- *   for (i = 0; i < lm_optB; i++) {
- *
- * we can probably get away with using lm_optB
- * in the while loop below
- *
- */
-       i = 0;
-
-       while (i++ < lm_optB) {
-               if (stat(optf, &sbuf) == -1)
-                       res->re_errors++;
-       }
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/lmbench_write.c b/tools/tests/libMicro/apple/lmbench_write.c
deleted file mode 100644 (file)
index 3224d4d..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#ifdef __sun
-#pragma ident  "@(#)write.c    1.3     05/08/04 Apple Inc."
-#endif
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "../libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-       int                     ts_fd;
-} tsd_t;
-
-#define        DEFF                    "/dev/null"
-#define        DEFS                    1024
-
-static int                     optc = 0;
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-static int                     optd;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "cdf:s:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-write (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-c ] (make sure buffer is in cache)\n"
-#ifdef __sun
-           "       [-d ] use directio"
-#endif
-           "notes: measures lmbench_write()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       lm_defB = 1;
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-
-       case 'd':
-               optd++;
-               break;
-       case 'c':
-               optc++;
-               break;
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       if (ts->ts_buf == NULL) {
-               ts->ts_buf = malloc(opts);
-               ts->ts_fd = open(optf, O_WRONLY);
-
-#ifdef __sun
-               if (optd)
-                       (void) directio(ts->ts_fd, DIRECTIO_ON);
-#endif
-               /*
-                * bring buf into cache if specified.
-                */
-
-               if (optc)
-                       for (i = 0; i < opts; i++)
-                               ts->ts_buf[i] = 0;
-       }
-
-       (void) lseek(ts->ts_fd, 0, SEEK_SET);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-/*
- * The libmicro test uses a for loop as below:
- *   for (i = 0; i < lm_optB; i++) {
- *
- * we can probably get away with using lm_optB
- * in the while loop below
- *
- */
-       i = 0;
-       
-       while (i++ < lm_optB) {
-               if (write(ts->ts_fd, ts->ts_buf, opts) != opts) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/apple/mbr_check_membership.c b/tools/tests/libMicro/apple/mbr_check_membership.c
deleted file mode 100644 (file)
index 91fbffe..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <membership.h>
-#include <pwd.h>
-#include <uuid/uuid.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    mbr_check_membership -E  -L -S -W -B 200 -C 10 -g 1211-1213 -u 5000-5200
-//
-//      libMicro default benchmark run options are "-E -C 200 -L -S -W"
-//
-// -B is batch size: loop iteration per each benchmark run. (default: 100)
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -u uid range in the form of "min-max". For example, -u 5000-5200
-// -g gid range or gid
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-} tsd_t;
-
-#define INVALID_ID  -1
-
-static uid_t uid_min = INVALID_ID;
-static gid_t gid_min = INVALID_ID;;
-
-static int   uid_range = 0;  // uid_max = uid_min + uid_range
-static int   gid_range = 0; // gid_max = gid_min + gid_range
-
-static uuid_t *u_uuid_list = NULL;  // user uuid list
-static uuid_t *g_uuid_list = NULL;  // group uuid list
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "g:u:");
-
-    lm_tsdsize = sizeof(tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n       ------- mbr_check_membership specific options\n"
-                "       [-u UID range (min-max)]\n"
-                "       [-g GID or GID range (gid or min-max)]\n"
-                "\n" );
-    return (0);
-}
-
-int
-parse_range(uint *min, int *offset, char *buf)
-{
-    char *value, *tmp_ptr = strdup(buf);
-    int range=0;
-    debug("parse_range");
-
-    value = strsep(&tmp_ptr, "-");
-    *min = atoi(value);
-    debug("min = %d", *min);
-    if (tmp_ptr) {
-        value = strsep(&tmp_ptr, "-");
-        range = atoi(value);
-        if (range < *min) {
-            printf("max id should be larger than min id\n");
-            return -1;
-        }
-        *offset = range - *min;
-        debug("range = %d", *offset);
-    }
-
-    return 0;
-
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'g':    // GID or GID range
-        return parse_range( &gid_min, &gid_range, optarg);
-        break;
-
-    case 'u':    // UID range
-        return parse_range( &uid_min, &uid_range, optarg);
-        break;
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-
-// Initialize all structures that will be used in benchmark()
-// 1. make local or network node for OD query
-// 2. create user key 
-int
-benchmark_initrun(void *tsd)
-{
-    int i;
-    //tsd_t *ts = (tsd_t *)tsd;
-
-    debug("benchmark_initrun");
-
-    if (uid_min == INVALID_ID || gid_min == INVALID_ID) {
-        printf("Both -u and -g need to be specified\n");
-        return -1;
-    }
-
-    // create an array of usernames to use in benchmark before their use
-    // realtime generation in benchmark effects performance measurements
-
-    u_uuid_list = malloc( sizeof(*u_uuid_list) * (uid_range+1) );
-    g_uuid_list = malloc( sizeof(*g_uuid_list) * (gid_range+1) );
-
-    for (i = 0; i <= uid_range; i++) {
-
-        if (mbr_uid_to_uuid(uid_min+i, u_uuid_list[i])) {
-            printf("error converting uid %d to UUID\n", uid_min+i);
-            return -1;
-        }
-    }
-
-    for (i = 0; i <= gid_range; i++) {
-
-        if (mbr_gid_to_uuid(gid_min+i, g_uuid_list[i])) {
-            printf("error converting gid %d to UUID\n", gid_min+i);
-            return -1;
-        }
-    }
-
-    return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    int         i, index, gindex, err, isMember=0;
-    //tsd_t *ts = (tsd_t *)tsd;
-
-#ifdef DEBUG
-    uid_t       uid;
-    int         id_type;
-#endif
-
-    res->re_errors = 0;
-
-    // debug("in to benchmark - optB = %i", lm_optB);
-
-    for (i = 0; i < lm_optB; i++) {
-
-        index = random() % (uid_range+1);
-        gindex = random() % (gid_range+1);
-        err = mbr_check_membership(u_uuid_list[index], g_uuid_list[gindex], &isMember);
-
-#ifdef DEBUG
-        //mbr_uuid_to_id(u_uuid_list[index], &uid, &id_type);
-        //debug ("loop %d: uid %d is %s (gindex %d)", i, uid, (isMember)?"member":"not a member", gindex);
-#endif
-
-        if (err) {
-            if (err == EIO) {
-                debug("mbr_check_membership returned EIO. Unable to communicate with DS daemon");
-            }
-            else if (err == ENOENT) {
-                debug("mbr_check_membership returned ENOENT. User not found");
-            }
-            else {
-                debug("error: %s", strerror(err));
-            }
-            res->re_errors++;
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-
-// We need to release all the structures we allocated in benchmark_initrun()
-int
-benchmark_finirun(void *tsd)
-{
-    //tsd_t    *ts = (tsd_t *)tsd;
-       
-    debug("benchmark_result: deallocating structures");
-
-    free(u_uuid_list);
-    free(g_uuid_list);
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/mbr_check_service_membership.c b/tools/tests/libMicro/apple/mbr_check_service_membership.c
deleted file mode 100644 (file)
index 47e3267..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <membership.h>
-#include <pwd.h>
-#include <uuid/uuid.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    mbr_check_service_membership -E  -L -S -W -B 200 -C 10 -r 100 -s "SACL" -u user_prefix
-//
-//      libMicro default benchmark run options are "-E -C 200 -L -S -W"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -r is the number of total records.
-// -s is SACL string: ie. "ssh"
-// -u user_prefix that preceeds the user number
-
-typedef struct {
-       uuid_t *uuid_list;
-} tsd_t;
-
-// the number of record lookup to issue is covered by standard option optB
-static int  optRecords =    100;  // the number of total records
-static int  optSACL = 0;          // option SACL specified?
-
-static char **sacl = NULL;
-static char *default_sacl[] = { "com.apple.access_dsproxy",
-                                "com.apple.access_screensharing",
-                                "com.apple.access_ssh",
-                                ""};
-static int  numSACL = 3;          // number of SACLs
-
-
-// This will use local users (local_test_*)
-static char *default_uprefix = "local_test_";
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "r:s:u:");
-
-    lm_tsdsize = sizeof(tsd_t);
-    lm_defB = 100;
-
-    (void) sprintf(lm_usage,
-                "\n       ------- mbr_check_service_membership specific options (default: *)\n"
-                "       [-r total number of records (100*)]\n"
-                "       [-s SACL]\n"
-               "       [-u user_prefix]\n"
-                "\n" );
-    return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'r':    // total number of records. default is 100
-        optRecords = atoi(optarg);
-        debug("optRecords = %d\n", optRecords);
-        break;
-
-    case 's':    // SACL
-        if (optSACL) {
-            printf("SACL already specified. Skipping");
-            break;
-        }
-        sacl = malloc(2 * sizeof(char *));
-        if (!sacl) {
-            printf("Error: no memory available for strdup\n");
-            return -1;
-        }
-        sacl[0] = strdup(optarg);
-        sacl[1] = "";
-        optSACL = 1;
-        numSACL = 1;
-
-        break;
-
-    case 'u':
-       default_uprefix = strdup(optarg);
-       debug("default_uprefix = %s\n", default_uprefix);
-       break;
-
-    default:
-        return -1;
-    }
-
-    return 0;
-}
-
-
-int
-benchmark_initrun()
-{
-    int i;
-    debug("benchmark_initrun");
-
-    if (!sacl) {
-        sacl = default_sacl;
-    }
-
-    for (i=0; strcmp(sacl[i], "") && i <= numSACL; i++) {
-        debug("SACL = %s", sacl[i]);
-    }
-
-    return (0);
-}
-
-// Initialize all structures that will be used in benchmark()
-// 1. make local or network node for OD query
-// 2. create user key 
-int
-benchmark_initworker(void *tsd)
-{
-    int i;
-    tsd_t *ts = (tsd_t *)tsd;
-    char *uprefix = default_uprefix;              // local user is default
-    char username[30] = "";
-    struct passwd *info = NULL;
-
-    debug("benchmark_initworker");
-
-    // create an array of usernames to use in benchmark before their use
-    // realtime generation in benchmark effects performance measurements
-
-    ts->uuid_list = calloc(optRecords, sizeof(uuid_t));
-
-    for (i = 0; i < optRecords; i++) {
-
-        sprintf(username, "%s%d", uprefix, i+1);
-        info = getpwnam(username);
-        if (!info) {
-            debug ("error converting username %s to uuid", username);
-            exit (1);
-        }
-
-        (void) mbr_uid_to_uuid(info->pw_uid, ts->uuid_list[i]);
-
-#if DEBUG
-        char buf[30];
-        uid_t uid;
-        int id_type; 
-        uuid_unparse(ts->uuid_list[i], buf);
-        mbr_uuid_to_id(ts->uuid_list[i], &uid, &id_type);
-        debug ("username (%s), uid %d, uuid %s, back to uid %d", username, info->pw_uid, buf, uid);
-#endif
-    }
-
-    // if batch size (one benchmark run) is less than the number records, adjust
-    // it to match the number record lookups in one batch run
-    if (optRecords < lm_optB) {
-        lm_optB = optRecords;
-        debug("Reducing batch size to %d to match the record #\n", lm_optB);
-    }
-
-    debug("benchmark_initworker");
-    return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-    tsd_t *ts = (tsd_t *)tsd;
-    int         i;
-    int         err;
-    int         isMember=0;
-    char        *sacl_chosen;
-
-#ifdef DEBUG
-    uid_t       uid;
-    int         id_type;
-#endif
-
-    res->re_errors = 0;
-
-    debug("in to benchmark - optB = %i", lm_optB);
-    for (i = 0; i < lm_optB; i++) {
-
-        sacl_chosen = sacl[random() % numSACL];
-        err = mbr_check_service_membership(ts->uuid_list[i], sacl_chosen, &isMember);
-
-#ifdef DEBUG
-        mbr_uuid_to_id(ts->uuid_list[i], &uid, &id_type);
-        debug ("loop %d: uid %d is %s a member of %s", i, uid, (isMember) ? "" : "not", sacl_chosen);
-#endif
-
-        if (err) {
-            debug("error: %s", strerror(err));
-            res->re_errors++;
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-
-// We need to release all the structures we allocated in benchmark_initworker()
-int
-benchmark_finiworker(void *tsd)
-{
-    tsd_t *ts = (tsd_t *)tsd;
-    debug("benchmark_result: deallocating structures");
-
-    free(ts->uuid_list);
-
-    return (0);
-}
-
-int
-benchmark_finirun(void *tsd)
-{
-       if (optSACL)
-        free(sacl);
-       
-       return 0;
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("benchmark_result");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/od_query_create_with_node.c b/tools/tests/libMicro/apple/od_query_create_with_node.c
deleted file mode 100644 (file)
index 7cf18ce..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-
-// add additional headers needed here.
-
-#include "../libmicro.h"
-#include <CoreFoundation/CFArray.h>
-#include <CoreFoundation/CFString.h>
-#include <CoreFoundation/CFDictionary.h>
-#include <OpenDirectory/OpenDirectory.h>
-#include <DirectoryService/DirectoryService.h>
-
-#if DEBUG
-# define debug(fmt, args...)    (void) fprintf(stderr, fmt , ##args)
-// # define debug(fmt, args...)    (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-
-// Correct use case
-//
-//    od_query_create_with_node -E  -L -S -W -B 200 -C 10 -c 100 -r 300
-//
-//      libMicro default benchmark run options are "-E -C 200 -L -S -W"
-//
-// -B is batch size: loop iteration per each benchmark run. Needs to match # of
-//                   real lookups. This is total number of lookups to issue.
-// -C is min sample number: how many benchmark needs to run to get proper sample
-//                          1 is mimumum, but you get at least 3 benchmark run
-//                          samples. Do not set to zero. Default is 200 for most
-//                          runs in libMicro.
-// -r is the number of total records. 
-// -c is the cache hit rate for lookup. set to 10%, you need -c 10.
-//                ie. -B 100 -c 50 -r 1000 -C 200 (out of 1000 records, I want 50%
-//                     lookup, and batch size is 100. 
-//                     To get 50% cache hit rate, you need 500 record lookups.
-//                     Batch size will be adjusted to 500 to get 500 record
-//                     lookup in each benchmark. If -r size is smaller than -B,
-//                     then -B will not be adjusted. 
-
-// Defining prefix for user and group name
-// make sure that these match the ones in LDAP records
-// ie. local_test_1 , od_test_4525, od_test_group_43, od_test_host_63
-#define LOCAL_U_PREFIX     CFSTR("local_test_")
-#define OD_U_PREFIX        CFSTR("od_test_")
-#define LOCAL_G_PREFIX     CFSTR("local_test_group_")
-#define OD_G_PREFIX        CFSTR("od_test_group_")
-#define LOCAL_H_PREFIX     CFSTR("local_test_host_")
-#define OD_H_PREFIX        CFSTR("od_test_host_")
-
-/*
- *    Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-    ODNodeRef    node;
-} tsd_t;
-
-// dsRecTypeStandard type dictionary
-enum {rectype_users=0, rectype_groups, rectype_hosts};
-CFStringRef rectype_dict[] = { CFSTR(kDSStdRecordTypeUsers),
-                               CFSTR(kDSStdRecordTypeGroups), 
-                               CFSTR(kDSStdRecordTypeHosts) };
-
-// the number of record lookup to issue is covered by standard option optB
-static int  optRecords =    100;  // the number of total records
-static int  optCachehit =   100;  // specify cache hit rate (% of record re-lookup)
-static bool optNodeLocal =  1;    // which node to search. Local node is default
-static int  optType =       rectype_users;    // dsRecType to search for. "Users"" is the default
-static const char *nodename = "/LDAPv3/127.0.0.1";
-
-static CFStringRef *key;                // username array
-
-// parse -t option and return enum type: user, group, and host
-// called by benchmark_optswitch()
-int
-ds_rec_type(char *name)
-{
-    if (strcasecmp("u", name) == 0) {
-        return (rectype_users);
-    } else if (strcasecmp("g", name) == 0) {
-        return (rectype_groups);
-    } else if (strcasecmp("h", name) == 0) {
-        return (rectype_hosts);
-    }
-
-    return (-1);
-}
-
-int
-benchmark_init()
-{
-    debug("benchmark_init");
-    (void) sprintf(lm_optstr,  "c:n:r:t:");
-
-    lm_tsdsize = sizeof (tsd_t);
-    lm_defB = 1000;
-
-    (void) sprintf(lm_usage,
-                "\n       ------- od_query_create_with_node specific options (default: *)\n"
-                "       [-c hitrate%% (100%%*)]\n"
-                "       [-r total number of records (100*)]\n"
-                "       [-n nodename] node name to use for test\n"
-                "       [-t record type: 'u'sers, 'g'roups, 'h'osts]\n"
-                "       use -B option to specify total number of record lookups to issue"
-                "\n" );
-    return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-    debug("benchmark_optswitch");
-
-    switch (opt) {
-    case 'c':    // cache hit rate. 100% means lookup the same records over and over
-        optCachehit = atoi(optarg);
-        debug("optCachehit = %d\n", optCachehit);
-        if (optCachehit > 100 || optCachehit < 0) {
-            printf("cache hit rate should be in between 0%% and 100%%");
-            return (-1);
-        }
-        break;
-
-    case 'r':    // total number of records. default is 100
-        optRecords = atoi(optarg);
-        debug("optRecords = %d\n", optRecords);
-        break;
-
-    case 'n':    // node
-        nodename = optarg;
-        break;
-
-    case 't':    // dsRecType: user, group, hots
-        optType = ds_rec_type(optarg);
-        debug("optType = %d\n", optType);
-
-        if (optType == -1) {
-            printf("wrong -t record type option\n");
-            return (-1);
-        }
-        break;
-
-    default:
-        return (-1);
-    }
-
-    return (0);
-}
-
-
-int
-benchmark_initrun()
-{
-    int i;
-    CFStringRef prefix;              // local user is default
-    
-    debug("benchmark_initrun\n");
-
-    // Adjust # of record lookups to reflect cache hit rate
-    if (optCachehit < 100) {
-        optRecords  = (int) ((float) optRecords * ((float) optCachehit / 100));
-        debug("# of records adjusted to %d for cache hit rate %d%%\n", optRecords, optCachehit);
-    }
-
-    // if batch size (one benchmark run) is less than the number records, adjust
-    // it to match the number record lookups in one batch run
-    if (lm_optB < optRecords) {
-        lm_optB = optRecords;
-        debug("Adjusting batch size to %d to match the lookups required in benchmark run\n", lm_optB);
-    }
-
-    switch (optType) {
-        case rectype_users:
-            prefix = (optNodeLocal) ? LOCAL_U_PREFIX : OD_U_PREFIX;
-            break;
-        case rectype_groups:
-            prefix = (optNodeLocal) ? LOCAL_G_PREFIX : OD_G_PREFIX;
-            break;
-        case rectype_hosts:
-            prefix = (optNodeLocal) ? LOCAL_H_PREFIX : OD_H_PREFIX;
-            break;
-    }
-    // create an array of usernames to use in benchmark before their use
-    // realtime generation in benchmark effects performance measurements
-
-    key = malloc(sizeof(CFStringRef) * optRecords);
-
-    // user, group, hosts key to lookup
-    switch (optType) {
-
-    case rectype_users:     // users query
-    case rectype_groups:    // groups query
-    case rectype_hosts:     // hosts query
-        for (i = 0; i < optRecords; i++) {
-            key[i] = CFStringCreateWithFormat( kCFAllocatorDefault, 
-                                               NULL, 
-                                               CFSTR("%@%d"), 
-                                               prefix, 
-                                               i+1);
-            // CFShow(key[i]);  // print user name to check
-        }
-        break;
-    }
-
-    return (0);
-}
-
-
-// Initialize all structures that will be used in benchmark()
-// 1. make local or network node for OD query
-// 2. create user key 
-int
-benchmark_initworker(void *tsd)
-{
-    CFErrorRef    error;
-    tsd_t *ts = (tsd_t *)tsd;
-
-    debug("benchmark_initworker: %s", (optNodeLocal) ? "local" : "network");
-
-
-    // create OD node for local or OD query
-    if (optNodeLocal) {
-        ts->node = ODNodeCreateWithNodeType(NULL, kODSessionDefault, kODNodeTypeLocalNodes, &error);
-    }
-    else {
-        CFStringRef nodenameStr = CFStringCreateWithCString(kCFAllocatorDefault, nodename, kCFStringEncodingUTF8);
-        ts->node = ODNodeCreateWithName(NULL, kODSessionDefault, nodenameStr, &error);
-        CFRelease(nodenameStr);
-    }
-
-    if (!ts->node) {
-        debug("error calling ODNodeCreateWithNodeType\n");
-        exit(1);
-    }
-
-    CFRetain (ts->node);
-
-    debug("benchmark_initworker: ODNodeRef = 0x%lx\n", ts->node);
-    return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-
-    tsd_t        *ts = (tsd_t *)tsd;
-    int          i;
-    ODNodeRef    node;
-    CFErrorRef   error;
-    CFArrayRef   results;
-    ODQueryRef   query;
-
-   res->re_errors = 0;
-    node = ts->node;
-
-    debug("in to benchmark - optB = %i, node = 0x%lx \n", lm_optB, node);
-    for (i = 0; i < lm_optB; i++) {
-
-        debug("loop %d: querying\n", i);
-        query = ODQueryCreateWithNode(NULL,
-                        node,                        // inNode
-                        rectype_dict[optType],       // inRecordTypeOrList
-                        CFSTR(kDSNAttrRecordName),   // inAttribute
-                        kODMatchInsensitiveEqualTo,  // inMatchType
-                        key[i % optRecords],                      // inQueryValueOrList
-                        NULL,                        // inReturnAttributeOrList
-                        1,                           // inMaxResults
-                        &error);
-
-        if (query) {
-            // we do not want to factually fetch the result in benchmark run
-            // debug("loop %d: calling ODQueryCopyResults\n", i);
-            results = ODQueryCopyResults(query, FALSE, &error);
-            CFRelease(query);
-            if (results) {
-#if DEBUG
-                int c;
-                c = CFArrayGetCount(results);
-                if (c > 0) {
-                    debug("Successful run: %d results, ", c);
-                }
-                else {
-                    debug("no result for ");
-                }
-                CFShow (key[i % optRecords]);
-                debug("\n");
-#endif
-                CFRelease(results);
-            }
-            else {
-                debug("loop %d: ODQueryCopyResults returned empty result for ", i);
-                res->re_errors++;
-                CFShow (key[i % optRecords]);
-                debug("\n");
-            } // if (results)
-
-        } // if (query)
-        else {
-            res->re_errors++;
-        }
-    }
-    res->re_count = i;
-
-    return (0);
-}
-
-
-// We need to release all the structures we allocated in benchmark_initworker()
-int
-benchmark_finiworker(void *tsd)
-{
-    tsd_t    *ts = (tsd_t *)tsd;
-
-    debug("benchmark_result: deallocating structures\n");
-
-    // free the node
-    if (ts->node)
-        CFRelease (ts->node);
-    ts->node = NULL;
-
-    return (0);
-}
-
-int
-benchmark_finirun()
-{
-    int i;
-
-    for (i = 0; i < optRecords; i++){
-        CFRelease(key[i]);
-    }
-
-    free(key);
-
-    return (0);
-}
-
-char *
-benchmark_result()
-{
-    static char    result = '\0';
-    debug("\n\n# of records adjusted to %d for cache hit rate %d%%\n", optRecords, optCachehit);
-    debug("benchmark_result\n");
-    return (&result);
-}
-
diff --git a/tools/tests/libMicro/apple/posix_spawn.c b/tools/tests/libMicro/apple/posix_spawn.c
deleted file mode 100644 (file)
index dc5167e..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2008 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#ifdef  __sun
-#pragma ident   "@(#)posix_spawn.c  1.0     08/21/08 Apple Inc."
-#endif
-
-/*
- * posix_spawn benchmark
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <spawn.h>
-
-#include "../libmicro.h"
-
-static char exec_path[1024];
-static char *argv[3];
-
-int
-benchmark_init()
-{
-       lm_defB = 128;
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "notes: measures posix_spawn time of simple process()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       char                    buffer[80];
-
-       (void) strcpy(exec_path, lm_procpath);
-       (void) strcat(exec_path, "/posix_spawn_bin");
-
-       (void) sprintf(buffer, "%d", lm_optB);
-       argv[0] = exec_path;
-       argv[1] = strdup(buffer);
-       argv[2] = NULL;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int c;
-       int pid;
-       int status;
-
-       if (( c = posix_spawn(&pid, exec_path, NULL, NULL, argv, NULL) != 0))
-       {
-               res->re_errors++;
-       }
-
-       if (waitpid(pid, &status, 0) < 0)
-       {
-               res->re_errors++;
-       }
-
-       if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
-       {
-               res->re_errors++;
-       }
-       
-       res->re_count = lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/posix_spawn_bin.c b/tools/tests/libMicro/apple/posix_spawn_bin.c
deleted file mode 100644 (file)
index a517336..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2008 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-#ifdef  __sun
-#pragma ident   "@(#)posix_spawn_bin.c  1.0     08/21/08 Apple Inc."
-#endif
-
-/*
- * time program to recursively test posix_spawn time
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <spawn.h>
-
-int
-main(int argc, char *argv[])
-{
-       int left;
-        int pid;
-
-       if (argc == 1) {
-               exit(1);
-       }
-
-       left = atoi(argv[1]);
-
-       left--;
-
-       if (left <= 0) {
-               exit(0);
-       } else {
-               char buffer[80];
-               (void) sprintf(buffer, "%d", left);
-               argv[1] = buffer;
-               if (posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL)) {
-                       exit(2);
-               }
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/apple/trivial.c b/tools/tests/libMicro/apple/trivial.c
deleted file mode 100644 (file)
index 97a051b..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)trivial.c  1.0     08/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-// add additional headers needed here.
-
-#include "../libmicro.h"
-
-#if DEBUG
-# define debug(fmt, args...)   (void) fprintf(stderr, fmt "\n" , ##args)
-#else
-# define debug(fmt, args...)
-#endif
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-        int     ts_once;
-} tsd_t;
-
-/*
- * You can have any lower-case option you want to define.
- * options are specified in the lm_optstr as either a 
- * single lower-case letter, or a single lower case letter 
- * with a colon after it.  In this example, you can optionally
- * specify -c {str} -e or -t {number}  
- *    -c takes a string (quote the string if blanks)
- *    -e is a boolean 
- *    -t takes a numeric
- * argument.
- */
-static char *  optc; // allocated in benchmark_init, freed in benchmark_fini.
-static bool    opte = false;
-static int             optt = 1;
-
-
-int
-benchmark_init()
-{
-       debug("benchmark_init\n");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "c:et:");
-       /*
-        *      tsd_t is the state info struct that we pass around 
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-               "               [-c string]\n"
-               "               [-e] optional parameter\n"
-           "       [-t int (default 1)]\n"
-           "notes: measures nothing\n");
-       
-       optc = malloc(20);
-       return (0);
-}
-
-/*
- * This is where you parse your lower-case arguments.
- * the format was defined in the lm_optstr assignment
- * in benchmark_init
- */
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       debug("benchmark_optswitch\n");
-       
-       switch (opt) {
-       case 'c':
-               strncpy(optc, optarg, 20);
-               debug("optc = %s\n", optc);
-               break;
-       case 'e':
-               opte = true;
-               debug("opte = %s\n", opte? "true": "false");
-               break;
-       case 't':
-               optt = sizetoint(optarg);
-               debug("optt = %d\n", optt);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       debug("benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       ts->ts_once = optt;
-       debug("benchmark_initworker: ts_once = %i\n",ts->ts_once);      
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       // useless code to show what you can do.
-        ts->ts_once++;
-        ts->ts_once--;
-       debug("benchmark_initbatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      try not to initialize things here.  This is the main
-        *  loop of things to get timed.  Start a server in 
-        *  benchmark_initbatch
-        */
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       
-       debug("in to benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-       for (i = 0; i < lm_optB; i++) {
-               /*
-                *      just to show that ts really contains state
-                */
-                ts->ts_once++;
-       }
-       res->re_count = i;
-       debug("out of benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       /* 
-        *      more proof of state passing
-        */
-       ts->ts_once = optt;
-       debug("benchmark_finibatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       // useless code to show what you can do.
-        ts->ts_once++;
-        ts->ts_once--;
-       debug("benchmark_finiworker: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       debug("benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finirun()
-{
-       debug("benchmark_finirun\n");
-       return (0);
-}
-
-
-int
-benchmark_fini()
-{
-       debug("benchmark_fini\n");
-       free(optc);
-       return (0);
-}
-
diff --git a/tools/tests/libMicro/apple/vm_allocate.c b/tools/tests/libMicro/apple/vm_allocate.c
deleted file mode 100644 (file)
index 0450f7a..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-
-/*
- *     Order of Execution
- *
- *     benchmark_init
- *
- *     benchmark_optswitch
- *
- *             benchmark_initrun
- *
- *                     benchmark_initworker
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch
- *                             benchmark_initbatch
- *                                     benchmark
- *                             benchmark_finibatch, etc.
- *                     benchmark_finiworker
- *
- *             benchmark_result
- *
- *             benchmark_finirun
- *
- *     benchmark_fini
- */
-
-
-
-#ifdef __sun
-#pragma ident  "@(#)vm_allocate.c      1.0     09/17/06 Apple Inc."
-#endif
-
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <mach/mach.h>
-
-#include "../libmicro.h"
-
-/*
- *     Your state variables should live in the tsd_t struct below
- */
-typedef struct {
-        int     ts_once;
-} tsd_t;
-
-unsigned char * arena;
-unsigned int    arenaSize = 1;
-
-static int     optt = 0;
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       /*
-        * initialize your state variables here second
-        */
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       //(void) fprintf(stderr, "benchmark_initbatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       (void) fprintf(stderr, "benchmark_finirun\n");
-       return (0);
-}
-
-int
-benchmark_init()
-{
-       (void) fprintf(stderr, "benchmark_init\n");
-       /* 
-        *      the lm_optstr must be defined here or no options for you
-        *
-        *      ...and the framework will throw an error
-        *
-        */
-       (void) sprintf(lm_optstr, "t:");
-       /*
-        *      working hypothesis:
-        *      
-        *      tsd_t is the struct that we can pass around our
-        *      state info in
-        *
-        *      lm_tsdsize will allocate the space we need for this
-        *      structure throughout the rest of the framework
-        */
-       lm_tsdsize = sizeof (tsd_t);
-       lm_defB = 1;
-
-
-       (void) sprintf(lm_usage,
-           "       [-t int (default 1)]\n"
-           "notes: measures nothing\n");
-       return (0);
-}
-
-int
-benchmark_fini()
-{
-       (void) fprintf(stderr, "benchmark_fini\n");
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       /* 
-        *      more proof of state passing
-        */
-       ts->ts_once = optt;
-       //(void) fprintf(stderr, "benchmark_finibatch: ts_once = %i\n",ts->ts_once);
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-       (void) fprintf(stderr, "benchmark_result\n");
-       return (&result);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       //(void) fprintf(stderr, "benchmark_finiworker: ts_once = %i\n",ts->ts_once);
-       //vm_deallocate( mach_task_self(), (vm_address_t) arena, arenaSize * vm_page_size);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       (void) fprintf(stderr, "benchmark_optswitch\n");
-       
-       switch (opt) {
-       case 't':
-               optt = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       /*
-        *      initialize your state variables here first
-        */
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       //ts->ts_once = optt;
-       //(void) fprintf(stderr, "benchmark_initworker: ts_once = %i\n",ts->ts_once);
-       if ( optt > 0 ) {
-               arenaSize = optt;
-       }
-       // warmup
-       vm_allocate( mach_task_self(), (vm_address_t *) &arena, arenaSize * vm_page_size, 1);
-       
-       vm_deallocate( mach_task_self(), (vm_address_t) arena, arenaSize * vm_page_size);
-       //arena = ( unsigned char * )malloc( arenaSize);
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       //(void) fprintf(stderr, "benchmark_initrun\n");
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       /* 
-        *      initialize your state variables here last
-        * 
-        *      and realize that you are paying for your initialization here
-        *      and it is really a bad idea
-        */
-       //tsd_t                 *ts = (tsd_t *)tsd;
-       int                     i;
-       
-       //(void) fprintf(stderr, "in to benchmark - optB = %i\n", lm_optB);
-       for (i = 0; i < lm_optB; i++) {
-               /*
-                *      just to show that ts really contains state
-                */
-                //(void) fprintf(stderr, "i is %i\n",i);
-               if (vm_allocate( mach_task_self(), (vm_address_t *) &arena, arenaSize * vm_page_size, 1))
-                       abort();
-               if (vm_deallocate( mach_task_self(), (vm_address_t) arena, arenaSize * vm_page_size))
-                       abort();
-
-       }
-       res->re_count = i;
-       //(void) fprintf(stderr, "out of benchmark - optB = %i : ts_once = %i\n", lm_optB, ts->ts_once);
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/atomic.c b/tools/tests/libMicro/atomic.c
deleted file mode 100644 (file)
index e005b46..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmarks atomic add on Solaris - useful for platform comparisons.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <atomic.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures atomic_add_32_nv()");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-static unsigned int value = 0;
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       unsigned int                    i;
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-               (void) atomic_add_32_nv(&value, 1);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/bench.sh b/tools/tests/libMicro/bench.sh
deleted file mode 100755 (executable)
index de0582b..0000000
+++ /dev/null
@@ -1,811 +0,0 @@
-#!/bin/sh
-#
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-# usage function - defines all the options that can be given to this script.
-function usage {
-       echo "Usage"
-       echo "$0 [-l] [-h] [name of test]"
-       echo "-l               : This option runs the lmbench tests along with the default libmicro tests."
-       echo "-h               : Help. This option displays information on how to run the script. "
-       echo "[name of test]   : This option runs only the test that is specified"
-       echo ""
-       echo "Examples"
-       echo "$0               : This is the defualt execution. This will run only the default libmicro tests."
-       echo "$0 -l            : This will run the lmbench tests too "
-       echo "$0 getppid       : This will run only the getppid tests"
-       exit
-       
-}
-
-if [ $# -eq 1 ]
-then 
-       lmbench=2    # to check if only a single test is to be run. e.g, ./bench.sh getppid
-else
-       lmbench=0    # to run the default libMicro tests, without the lmbench tests.
-fi
-
-while getopts "lh" OPT_LIST
-do
-       case $OPT_LIST in 
-               l) lmbench=1;;    # to run the libmicro tests including the lmbench tests.
-               h) usage;;
-               *) usage;;
-       esac
-done
-
-
-
-tattle="./tattle"
-
-bench_version=0.4.0
-libmicro_version=`$tattle -V`
-
-case $libmicro_version in
-$bench_version)
-       ;;
-*)
-       echo "ERROR: libMicro version doesn't match 'bench' script version"
-       exit 1
-esac
-
-TMPROOT=/private/tmp/libmicro.$$
-VARROOT=/private/var/tmp/libmicro.$$
-mkdir -p $TMPROOT
-mkdir -p $VARROOT
-trap "rm -rf $TMPROOT $VARROOT && exit" 0 2
-
-TFILE=$TMPROOT/data
-IFILE=$TMPROOT/ifile
-TDIR1=$TMPROOT/0/1/2/3/4/5/6/7/8/9
-TDIR2=$TMPROOT/1/2/3/4/5/6/7/8/9/0
-VFILE=$VARROOT/data
-VDIR1=$VARROOT/0/1/2/3/4/5/6/7/8/9
-VDIR2=$VARROOT/1/2/3/4/5/6/7/8/9/0
-
-
-OPTS="-E -C 200 -L -S -W"
-
-dd if=/dev/zero of=$TFILE bs=1024k count=10 2>/dev/null
-dd if=/dev/zero of=$VFILE bs=1024k count=10 2>/dev/null
-mkdir -p $TDIR1 $TDIR2
-mkdir -p $VDIR1 $VDIR2
-
-touch $IFILE
-/usr/bin/touch /private/var/tmp/lmbench
-
-
-# produce benchmark header for easier comparisons
-
-hostname=`uname -n`
-
-if [ -f /usr/sbin/psrinfo ]; then
-       p_count=`psrinfo|wc -l`
-       p_mhz=`psrinfo -v | awk '/operates/{print $6 "MHz"; exit }'`
-       p_type=`psrinfo -vp 2>/dev/null | awk '{if (NR == 3) {print $0; exit}}'` 
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-fi
-
-if [ -f /proc/cpuinfo ]; then
-       p_count=`egrep processor /proc/cpuinfo | wc -l`
-       p_mhz=`awk -F: '/cpu MHz/{printf("%5.0f00Mhz\n",$2/100); exit}' /proc/cpuinfo`
-       p_type=`awk -F: '/model name/{print $2; exit}' /proc/cpuinfo`
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-else
-## Mac OS X specific stuff
-# first, get ugly output, in case pretty output isn't available
-#
-       p_count=`sysctl -n hw.physicalcpu`
-       p_mhz=`sysctl -n hw.cpufrequency`
-       p_type=`sysctl -n hw.model`
-
-if [ -x /usr/sbin/system_profiler ]; then
-       # <rdar://4655981> requires this hunk of work-around
-       # grep the XML for the characteristic we need. The key appears twice, so grep for the useful key (with 'string')
-       # use sed to strip off the <string></string> and the tabs in front of the string.  So much work for so little result.
-       #
-               p_mhz=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 current_processor_speed | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-               p_type=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 cpu_type | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-fi
-
-# look for en0 (usually ethernet) if that isn't there try en1 (usually wireless) else give up
-       p_ipaddr=`ipconfig getpacket en0 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       if [ ! $p_ipaddr  ]; then
-               p_ipaddr=`ipconfig getpacket en1 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       elif [ ! $p_ipaddr ]; then
-               p_ipaddr="unknown"
-       fi
-fi
-
-printf "\n\n!Libmicro_#:   %30s\n" $libmicro_version
-printf "!Options:      %30s\n" "$OPTS"
-printf "!Machine_name: %30s\n" "$hostname"
-printf "!OS_name:      %30s\n" `uname -s`
-printf "!OS_release:   %30s\n" `sw_vers -productVersion`
-printf "!OS_build:     %30.18s\n" "`sw_vers -buildVersion`"
-printf "!Kernel:       %30.50s\n" "`uname -v|cut -d ' ' -f 11`"
-printf "!Processor:    %30s\n" `arch`
-printf "!#CPUs:        %30s\n" $p_count
-printf "!CPU_MHz:      %30s\n" "$p_mhz"
-printf "!CPU_NAME:     %30s\n" "$p_type"
-printf "!IP_address:   %30s\n" "$p_ipaddr"
-printf "!Run_by:       %30s\n" $LOGNAME
-printf "!Date:        %30s\n" "`date '+%D %R'`"
-printf "!Compiler:     %30s\n" `$tattle -c`
-printf "!Compiler Ver.:%30s\n" "`$tattle -v`"
-printf "!sizeof(long): %30s\n" `$tattle -s`
-printf "!extra_CFLAGS: %30s\n" "`$tattle -f`"
-printf "!TimerRes:     %30s\n\n\n" "`$tattle -r`"
-bin_dir="$TMPROOT/bin"
-
-mkdir -p $bin_dir
-cp bin-*/exec_bin $bin_dir/$A
-
-cp ./apple/bin-*/posix_spawn_bin $bin_dir/$A
-
-newline=0
-
-#
-# Everything below the while loop is input for the while loop if
-# you have any tests which can't run in the while loop, put
-# them above this comment
-#
-while read A B
-do
-       # $A contains the command, $B contains the arguments
-       # we echo blank lines and comments
-       # we skip anything which fails to match *$1* (useful if
-       # we only want to test one case, but a nasty hack)
-
-       case $A in
-       \#*)
-               echo "$A $B"
-               newline=1
-               continue
-               ;;
-       
-       "")
-               if [ $newline -eq 1 ]
-               then
-                       newline=0
-                       echo
-                       echo
-               fi
-
-               continue
-               ;;
-
-       *$1*)
-               # Default execution without the lmbench tests. 
-               # checks if there is no argument passed by the user.
-               if [  $lmbench -eq 0 ]
-               then
-                       string=lmbench
-                       if [ "${A:0:7}" == "$string" ]
-                       then
-                               continue
-                       fi
-               fi
-                       
-               ;;
-       
-       *)              
-               if [ $lmbench -ne 1 ]
-               then
-                       continue
-               fi
-               ;;
-       esac
-
-       if [ ! -f $bin_dir/$A ]
-       then
-               cp bin-*/$A $bin_dir/$A
-       fi
-
-       echo
-
-       (cd $TMPROOT && eval "bin/$A $B")
-
-       echo
-       echo
-done <<.
-
-#
-# Obligatory null system call: use very short time
-# for default since SuSe implements this "syscall" in userland
-#
-
-getpid         $OPTS -N "getpid" -I 5
-getppid                $OPTS -N "getppid" -I 5
-
-getenv         $OPTS -N "getenv"       -s 100 -I 100    
-getenv         $OPTS -N "getenvT2"     -s 100 -I 100   -T 2 
-
-gettimeofday   $OPTS -N "gettimeofday"          
-
-log            $OPTS -N "log"  -I 20   -B 300000        
-exp            $OPTS -N "exp"  -I 20   -B 100000        
-lrand48                $OPTS -N "lrand48"
-
-memset         $OPTS -N "memset_10"    -s 10   -I 10 
-memset         $OPTS -N "memset_256"   -s 256  -I 20
-memset         $OPTS -N "memset_256_u" -s 256   -a 1 -I 20 
-memset         $OPTS -N "memset_1k"    -s 1k    -I 100 -B 2000
-memset         $OPTS -N "memset_4k"    -s 4k    -I 250 -B 500
-memset         $OPTS -N "memset_4k_uc" -s 4k    -u -I 400
-
-memset         $OPTS -N "memset_10k"   -s 10k  -I 600 -B 500
-memset         $OPTS -N "memset_1m"    -s 1m   -I 200000
-memset         $OPTS -N "memset_10m"   -s 10m -I 2000000 
-memset         $OPTS -N "memsetP2_10m" -s 10m -P 2 -I 2000000 
-
-memrand                $OPTS -N "memrand"      -s 40m -B 10000
-
-# This is an elided test and is not ported yet.
-# Check Makefile.darwin for list of elided tests  
-# cachetocache $OPTS -N "cachetocache" -s 100k -T 2 -I 200
-
-isatty         $OPTS -N "isatty_yes"   
-isatty         $OPTS -N "isatty_no"  -f $IFILE
-
-malloc         $OPTS -N "malloc_10"    -s 10    -g 10 -I 50
-malloc         $OPTS -N "malloc_100"   -s 100   -g 10 -I 50
-malloc         $OPTS -N "malloc_1k"    -s 1k    -g 10 -I 50
-malloc         $OPTS -N "malloc_10k"   -s 10k   -g 10 -I 50
-malloc         $OPTS -N "malloc_100k"  -s 100k  -g 10 -I 2000
-
-malloc         $OPTS -N "mallocT2_10"    -s 10   -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_100"   -s 100  -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_1k"    -s 1k   -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_10k"   -s 10k  -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_100k"  -s 100k -g 10 -T 2 -I 10000
-
-close          $OPTS -N "close_bad"            -B 96           -b
-close          $OPTS -N "close_tmp"            -B 64           -f $TFILE
-close          $OPTS -N "close_usr"            -B 64           -f $VFILE
-close          $OPTS -N "close_zero"           -B 64           -f /dev/zero
-close_tcp      $OPTS -N "close_tcp"            -B 32  
-
-memcpy         $OPTS -N "memcpy_10"    -s 10   -I 10 
-memcpy         $OPTS -N "memcpy_1k"    -s 1k   -I 50
-memcpy         $OPTS -N "memcpy_10k"   -s 10k  -I 800
-memcpy         $OPTS -N "memcpy_1m"    -s 1m   -I 500000
-memcpy         $OPTS -N "memcpy_10m"   -s 10m  -I 5000000
-
-strcpy         $OPTS -N "strcpy_10"    -s 10   -I 5 
-strcpy         $OPTS -N "strcpy_1k"    -s 1k   -I 100
-
-strlen         $OPTS -N "strlen_10"    -s 10   -I 5
-strlen         $OPTS -N "strlen_1k"    -s 1k   -I 100
-
-strchr         $OPTS -N "strchr_10"    -s 10   -I 5
-strchr         $OPTS -N "strchr_1k"    -s 1k   -I 200
-strcmp         $OPTS -N "strcmp_10"    -s 10   -I 10
-strcmp         $OPTS -N "strcmp_1k"    -s 1k   -I 200
-
-strcasecmp     $OPTS -N "scasecmp_10"  -s 10 -I 50 -B 2000
-strcasecmp     $OPTS -N "scasecmp_1k"  -s 1k -I 20000 -B 100
-
-strtol         $OPTS -N "strtol"      -I 20      
-
-# This is an elided test and is not ported yet.     
-# Check Makefile.darwin for list of elided tests
-# getcontext   $OPTS -N "getcontext"  -I 100
-
-# This is an elided test and is not ported yet.     
-# Check Makefile.darwin for list of elided tests
-# setcontext   $OPTS -N "setcontext"  -I 100
-
-mutex          $OPTS -N "mutex_st"     -I 10
-mutex          $OPTS -N "mutex_mt"     -t -I 10        
-mutex          $OPTS -N "mutex_T2"     -T 2  -I 100
-
-longjmp                $OPTS -N "longjmp"      -I 10
-siglongjmp     $OPTS -N "siglongjmp"   -I 20
-
-getrusage      $OPTS -N "getrusage"    -I 200
-
-times          $OPTS -N "times"        -I 200
-time           $OPTS -N "time"         -I 50
-localtime_r    $OPTS -N "localtime_r"  -I 200  
-strftime       $OPTS -N "strftime" -I 10000 -B 100 
-
-mktime         $OPTS -N "mktime"       -I 500   
-mktime         $OPTS -N "mktimeT2" -T 2 -I 1000 
-
-cascade_mutex  $OPTS -N "c_mutex_1"    -I 50
-cascade_mutex  $OPTS -N "c_mutex_10"   -T 10 -I 5000
-cascade_mutex  $OPTS -N "c_mutex_200"  -T 200  -I 2000000
-
-cascade_cond   $OPTS -N "c_cond_1"     -I 100
-cascade_cond   $OPTS -N "c_cond_10"    -T 10   -I 3000
-cascade_cond   $OPTS -N "c_cond_200"   -T 200  -I 2000000
-
-cascade_lockf  $OPTS -N "c_lockf_1"    -I 1000 
-cascade_lockf  $OPTS -N "c_lockf_10"   -P 10 -I 50000
-cascade_lockf  $OPTS -N "c_lockf_200"  -P 200 -I 5000000
-
-cascade_flock  $OPTS -N "c_flock"      -I 1000 
-cascade_flock  $OPTS -N "c_flock_10"   -P 10   -I 50000
-cascade_flock  $OPTS -N "c_flock_200"  -P 200  -I 5000000
-
-cascade_fcntl  $OPTS -N "c_fcntl_1"    -I 2000         
-cascade_fcntl  $OPTS -N "c_fcntl_10"   -P 10 -I 20000
-cascade_fcntl  $OPTS -N "c_fcntl_200"  -P 200  -I 5000000
-
-file_lock      $OPTS -N "file_lock"   -I 1000         
-
-getsockname    $OPTS -N "getsockname"  -I 100
-getpeername    $OPTS -N "getpeername"  -I 100
-
-chdir          $OPTS -N "chdir_tmp"    -I 2000         $TDIR1 $TDIR2
-chdir          $OPTS -N "chdir_usr"    -I 2000         $VDIR1 $VDIR2
-
-chdir          $OPTS -N "chgetwd_tmp"  -I 3000 -g $TDIR1 $TDIR2
-chdir          $OPTS -N "chgetwd_usr"  -I 3000 -g $VDIR1 $VDIR2
-
-realpath       $OPTS -N "realpath_tmp" -I 3000         -f $TDIR1
-realpath       $OPTS -N "realpath_usr" -I 3000 -f $VDIR1
-
-stat           $OPTS -N "stat_tmp" -I 1000             -f $TFILE
-stat           $OPTS -N "stat_usr" -I 1000             -f $VFILE
-
-lmbench_stat           $OPTS -N "lmbench_stat_tmp" -I 1000             -f $TFILE
-lmbench_stat           $OPTS -N "lmbench_stat_usr" -I 10000 -B 100             -f /private/var/tmp/lmbench
-
-#
-# lmbench uses a touched empty file in /private/var/tmp
-# libMicro uses a 1M file in a directory off /private/var/tmp
-# performance difference is ~ 0.2 usecs/call
-#
-# why? - walking the dir tree, empty file vs. non-empty file, non-empty dir
-# in the case of libMicro, etc., etc.
-#
-
-lmbench_stat           $OPTS -N "lmbench_stat_usr - Default" -I 10000 -B 100   -f /private/var/tmp/lmbench
-
-lmbench_fstat          $OPTS -N "lmbench_fstat_tmp" -I 1000            -f $TFILE
-lmbench_fstat          $OPTS -N "lmbench_fstat_usr" -I 10000 -B 100            -f /private/var/tmp/lmbench
-
-# see stat test to understand why we are using /private/var/tmp/lmbench
-
-lmbench_fstat          $OPTS -N "lmbench_fstat_usr - Default" -I 10000 -B 100  -f /private/var/tmp/lmbench
-
-lmbench_openclose      $OPTS -N "lmbench_openclose - Default" -I 10000 -B 100  -f /private/var/tmp/lmbench
-
-lmbench_select_file $OPTS -N "lmbench_select_file_10"  -n 10  -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_100" -n 100 -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_250" -n 250 -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_500" -n 500 -B 100
-
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_10"  -n 10  -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_100" -n 100 -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_250" -n 250 -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_500" -n 500 -B 100
-
-fcntl          $OPTS -N "fcntl_tmp"    -I 100  -f $TFILE
-fcntl          $OPTS -N "fcntl_usr"    -I 100  -f $VFILE
-fcntl_ndelay   $OPTS -N "fcntl_ndelay" -I 100  
-
-lseek          $OPTS -N "lseek_t8k"    -s 8k   -I 50   -f $TFILE
-lseek          $OPTS -N "lseek_u8k"    -s 8k   -I 50   -f $VFILE
-
-open           $OPTS -N "open_tmp"             -B 256          -f $TFILE
-open           $OPTS -N "open_usr"             -B 256          -f $VFILE
-open           $OPTS -N "open_zero"            -B 256          -f /dev/zero
-
-dup            $OPTS -N "dup"                  -B 512   
-
-socket         $OPTS -N "socket_u"             -B 256
-socket         $OPTS -N "socket_i"             -B 256          -f PF_INET
-
-socketpair     $OPTS -N "socketpair"           -B 256
-
-setsockopt     $OPTS -N "setsockopt"           -I 200
-
-bind           $OPTS -N "bind"                 -B 100
-
-listen         $OPTS -N "listen"               -B 100
-
-#connection    $OPTS -N "connection"           -B 256 
-
-poll           $OPTS -N "poll_10"      -n 10   -I 500
-poll           $OPTS -N "poll_100"     -n 100  -I 1000
-poll           $OPTS -N "poll_1000"    -n 1000 -I 5000
-
-poll           $OPTS -N "poll_w10"     -n 10   -I 500          -w 1
-poll           $OPTS -N "poll_w100"    -n 100  -I 2000         -w 10
-poll           $OPTS -N "poll_w1000"   -n 1000 -I 40000        -w 100
-
-select         $OPTS -N "select_10"    -n 10   -I 500
-select         $OPTS -N "select_100"   -n 100  -I 1000
-select         $OPTS -N "select_1000"  -n 1000 -I 5000
-
-select         $OPTS -N "select_w10"   -n 10   -I 500          -w 1
-select         $OPTS -N "select_w100"  -n 100  -I 2000         -w 10
-select         $OPTS -N "select_w1000" -n 1000 -I 40000        -w 100
-
-semop          $OPTS -N "semop" -I 200
-
-sigaction      $OPTS -N "sigaction" -I 100
-signal         $OPTS -N "signal" -I 1000
-sigprocmask    $OPTS -N "sigprocmask" -I 200
-
-lmbench_lat_sig_install        $OPTS -N "lmbench_siginstall"
-# sigcatch and sigsend need to be evaluated together
-# lmbench framework will allow multiple measurements within the same
-# benchmark test which allow them to factor out the cost of sending
-# a signal from catching one
-#
-# for our purposes sigcatch results - sigsend results yield
-# lmbench sig handler overhead measurements
-lmbench_lat_sig_catch  $OPTS -N "lmbench_sigcatch" 
-lmbench_lat_sig_send   $OPTS -N "lmbench_sigsend" 
-
-
-pthread_create  $OPTS -N "pthread_8"           -B 8
-pthread_create  $OPTS -N "pthread_32"          -B 32
-pthread_create  $OPTS -N "pthread_128"         -B 128
-pthread_create  $OPTS -N "pthread_512"         -B 512
-
-fork           $OPTS -N "fork_10"              -B 10
-fork           $OPTS -N "fork_100"             -B 100  -C 100
-
-#fork          $OPTS -N "fork_1000"            -B 1000 -C 50
-
-exit           $OPTS -N "exit_10"              -B 10
-exit           $OPTS -N "exit_100"             -B 100
-
-#exit          $OPTS -N "exit_1000"            -B 1000 -C 50
-
-exit           $OPTS -N "exit_10_nolibc"       -e -B 10
-
-exec           $OPTS -N "exec" -B 10
-
-posix_spawn    $OPTS -N "posix_spawn" -B 10
-
-system         $OPTS -N "system" -I 1000000
-
-recurse                $OPTS -N "recurse"              -B 512
-
-read           $OPTS -N "read_t1k"     -s 1k -B 50                     -f $TFILE
-read           $OPTS -N "read_t10k"    -s 10k  -B 16           -f $TFILE
-read           $OPTS -N "read_t100k"   -s 100k -B 4            -f $TFILE
-
-read           $OPTS -N "read_u1k"     -s 1k   -B 50           -f $VFILE
-read           $OPTS -N "read_u10k"    -s 10k  -B 16           -f $VFILE
-read           $OPTS -N "read_u100k"   -s 100k -B 4            -f $VFILE
-
-read           $OPTS -N "read_z1k"     -s 1k   -B 100          -f /dev/zero 
-read           $OPTS -N "read_z10k"    -s 10k  -B 30           -f /dev/zero 
-read           $OPTS -N "read_z100k"   -s 100k -B 4            -f /dev/zero 
-read           $OPTS -N "read_zw100k"  -s 100k -B 4         -w -f /dev/zero 
-
-lmbench_read           $OPTS -N "read_t1b"     -s 1 -B 50                      -f $TFILE
-lmbench_read           $OPTS -N "read_t1k"     -s 1k -B 50                     -f $TFILE
-lmbench_read           $OPTS -N "read_t10k"    -s 10k  -B 16           -f $TFILE
-lmbench_read           $OPTS -N "read_t100k"   -s 100k -B 4            -f $TFILE
-
-lmbench_read           $OPTS -N "read_u1b"     -s 1    -B 50           -f $VFILE
-lmbench_read           $OPTS -N "read_u1k"     -s 1k   -B 50           -f $VFILE
-lmbench_read           $OPTS -N "read_u10k"    -s 10k  -B 16           -f $VFILE
-lmbench_read           $OPTS -N "read_u100k"   -s 100k -B 4            -f $VFILE
-
-lmbench_read           $OPTS -N "read_z1b - Default"   -s 1    -B 100          -f /dev/zero 
-lmbench_read           $OPTS -N "read_z1k"     -s 1k   -B 100          -f /dev/zero 
-lmbench_read           $OPTS -N "read_z10k"    -s 10k  -B 30           -f /dev/zero 
-lmbench_read           $OPTS -N "read_z100k"   -s 100k -B 4            -f /dev/zero 
-lmbench_read           $OPTS -N "read_zw100k"  -s 100k -B 4         -w -f /dev/zero 
-
-write          $OPTS -N "write_t1k"    -s 1k   -B 50           -f $TFILE
-write          $OPTS -N "write_t10k"   -s 10k  -B 25           -f $TFILE
-write          $OPTS -N "write_t100k"  -s 100k -B 4            -f $TFILE
-
-write          $OPTS -N "write_u1k"    -s 1k   -B 50           -f $VFILE
-write          $OPTS -N "write_u10k"   -s 10k  -B 25           -f $VFILE
-write          $OPTS -N "write_u100k"  -s 100k -B 4            -f $VFILE
-
-write          $OPTS -N "write_n1k"    -s 1k   -I 100 -B 0     -f /dev/null 
-write          $OPTS -N "write_n10k"   -s 10k  -I 100 -B 0     -f /dev/null 
-write          $OPTS -N "write_n100k"  -s 100k -I 100 -B 0     -f /dev/null 
-
-lmbench_write          $OPTS -N "lmbench_write_t1b"    -s 1    -B 50           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t1k"    -s 1k   -B 50           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t10k"   -s 10k  -B 25           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t100k"  -s 100k -B 4            -f $TFILE
-
-lmbench_write          $OPTS -N "lmbench_write_u1b"    -s 1    -B 50           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u1k"    -s 1k   -B 50           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u10k"   -s 10k  -B 25           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u100k"  -s 100k -B 4            -f $VFILE
-
-lmbench_write          $OPTS -N "lmbench_write_n1b - Default"  -s 1    -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n1k"    -s 1k   -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n10k"   -s 10k  -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n100k"  -s 100k -I 100 -B 0     -f /dev/null 
-
-writev         $OPTS -N "writev_t1k"   -s 1k   -B 20           -f $TFILE
-writev         $OPTS -N "writev_t10k"  -s 10k  -B 4            -f $TFILE
-writev         $OPTS -N "writev_t100k" -s 100k                 -f $TFILE
-
-writev         $OPTS -N "writev_u1k"   -s 1k   -B 20           -f $VFILE
-writev         $OPTS -N "writev_u10k"  -s 10k  -B 4            -f $VFILE
-writev         $OPTS -N "writev_u100k" -s 100k                 -f $VFILE
-
-writev         $OPTS -N "writev_n1k"   -s 1k   -I 100 -B 0     -f /dev/null 
-writev         $OPTS -N "writev_n10k"  -s 10k  -I 100 -B 0     -f /dev/null 
-writev         $OPTS -N "writev_n100k" -s 100k -I 100 -B 0     -f /dev/null 
-
-pread          $OPTS -N "pread_t1k"    -s 1k   -I 300          -f $TFILE
-pread          $OPTS -N "pread_t10k"   -s 10k  -I 1000         -f $TFILE
-pread          $OPTS -N "pread_t100k"  -s 100k -I 10000        -f $TFILE
-
-pread          $OPTS -N "pread_u1k"    -s 1k   -I 300          -f $VFILE
-pread          $OPTS -N "pread_u10k"   -s 10k  -I 1000         -f $VFILE
-pread          $OPTS -N "pread_u100k"  -s 100k -I 10000        -f $VFILE
-
-pread          $OPTS -N "pread_z1k"    -s 1k   -I 300          -f /dev/zero 
-pread          $OPTS -N "pread_z10k"   -s 10k  -I 1000         -f /dev/zero 
-pread          $OPTS -N "pread_z100k"  -s 100k -I 2000 -f /dev/zero 
-pread          $OPTS -N "pread_zw100k" -s 100k -w -I 10000     -f /dev/zero 
-
-pwrite         $OPTS -N "pwrite_t1k"   -s 1k   -I 500          -f $TFILE
-pwrite         $OPTS -N "pwrite_t10k"  -s 10k  -I 1000         -f $TFILE
-pwrite         $OPTS -N "pwrite_t100k" -s 100k -I 10000        -f $TFILE
-
-pwrite         $OPTS -N "pwrite_u1k"   -s 1k   -I 500          -f $VFILE
-pwrite         $OPTS -N "pwrite_u10k"  -s 10k  -I 1000         -f $VFILE
-pwrite         $OPTS -N "pwrite_u100k" -s 100k -I 20000        -f $VFILE
-
-pwrite         $OPTS -N "pwrite_n1k"   -s 1k   -I 100          -f /dev/null 
-pwrite         $OPTS -N "pwrite_n10k"  -s 10k  -I 100          -f /dev/null 
-pwrite         $OPTS -N "pwrite_n100k" -s 100k -I 100          -f /dev/null 
-
-mmap           $OPTS -N "mmap_z8k"     -l 8k   -I 1000 -B 50   -f /dev/zero
-mmap           $OPTS -N "mmap_z128k"   -l 128k -I 2000 -B 100  -f /dev/zero
-mmap           $OPTS -N "mmap_t8k"     -l 8k   -I 1000         -f $TFILE
-mmap           $OPTS -N "mmap_t128k"   -l 128k -I 1000         -f $TFILE
-mmap           $OPTS -N "mmap_u8k"     -l 8k   -I 1000         -f $VFILE
-mmap           $OPTS -N "mmap_u128k"   -l 128k -I 1000         -f $VFILE
-mmap           $OPTS -N "mmap_a8k"     -l 8k   -I 200          -f MAP_ANON
-mmap           $OPTS -N "mmap_a128k"   -l 128k -I 200          -f MAP_ANON
-
-
-mmap           $OPTS -N "mmap_rz8k"    -l 8k   -I 2000 -r      -f /dev/zero
-mmap           $OPTS -N "mmap_rz128k"  -l 128k -I 2000 -r      -f /dev/zero
-mmap           $OPTS -N "mmap_rt8k"    -l 8k   -I 2000 -r      -f $TFILE
-mmap           $OPTS -N "mmap_rt128k"  -l 128k -I 20000 -r     -f $TFILE
-mmap           $OPTS -N "mmap_ru8k"    -l 8k   -I 2000 -r      -f $VFILE
-mmap           $OPTS -N "mmap_ru128k"  -l 128k -I 20000 -r     -f $VFILE
-mmap           $OPTS -N "mmap_ra8k"    -l 8k   -I 2000 -r      -f MAP_ANON
-mmap           $OPTS -N "mmap_ra128k"  -l 128k -I 20000 -r     -f MAP_ANON
-
-mmap           $OPTS -N "mmap_wz8k"    -l 8k   -I 5000 -w      -B 50 -f /dev/zero
-mmap           $OPTS -N "mmap_wz128k"  -l 128k -I 50000 -w     -B 50 -f /dev/zero
-mmap           $OPTS -N "mmap_wt8k"    -l 8k   -I 5000 -w      -f $TFILE
-mmap           $OPTS -N "mmap_wt128k"  -l 128k -I 50000 -w     -f $TFILE
-mmap           $OPTS -N "mmap_wu8k"    -l 8k   -I 5000 -w      -f $VFILE
-mmap           $OPTS -N "mmap_wu128k"  -l 128k -I 500000 -w    -f $VFILE
-mmap           $OPTS -N "mmap_wa8k"    -l 8k   -I 3000 -w      -f MAP_ANON
-mmap           $OPTS -N "mmap_wa128k"  -l 128k -I 50000 -w     -f MAP_ANON
-
-munmap         $OPTS -N "unmap_z8k"    -l 8k   -I 500          -f /dev/zero
-munmap         $OPTS -N "unmap_z128k"  -l 128k -I 500  -B 100  -f /dev/zero
-munmap         $OPTS -N "unmap_t8k"    -l 8k   -I 500          -f $TFILE
-munmap         $OPTS -N "unmap_t128k"  -l 128k -I 500          -f $TFILE
-munmap         $OPTS -N "unmap_u8k"    -l 8k   -I 500          -f $VFILE
-munmap         $OPTS -N "unmap_u128k"  -l 128k -I 500          -f $VFILE
-munmap         $OPTS -N "unmap_a8k"    -l 8k   -I 500          -f MAP_ANON
-munmap         $OPTS -N "unmap_a128k"  -l 128k -I 500          -f MAP_ANON
-
-munmap         $OPTS -N "unmap_rz8k"   -l 8k   -I 1000 -r      -f /dev/zero
-munmap         $OPTS -N "unmap_rz128k" -l 128k -I 2000 -r      -B 100 -f /dev/zero
-munmap         $OPTS -N "unmap_rt8k"   -l 8k   -I 1000 -r      -f $TFILE
-munmap         $OPTS -N "unmap_rt128k" -l 128k -I 3000 -r      -f $TFILE
-munmap         $OPTS -N "unmap_ru8k"   -l 8k   -I 1000 -r      -f $VFILE
-munmap         $OPTS -N "unmap_ru128k" -l 128k -I 3000 -r      -f $VFILE
-munmap         $OPTS -N "unmap_ra8k"   -l 8k   -I 1000 -r      -f MAP_ANON
-munmap         $OPTS -N "unmap_ra128k" -l 128k -I 2000 -r      -f MAP_ANON
-
-connection     $OPTS -N "conn_connect"         -B 256  -c
-
-munmap         $OPTS -N "unmap_wz8k"   -l 8k   -I 1000 -w      -f /dev/zero
-munmap         $OPTS -N "unmap_wz128k" -l 128k -I 8000 -w      -B 100 -f /dev/zero
-munmap         $OPTS -N "unmap_wt8k"   -l 8k   -I 1000 -w      -f $TFILE
-munmap         $OPTS -N "unmap_wt128k" -l 128k -I 10000        -w      -f $TFILE
-munmap         $OPTS -N "unmap_wu8k"   -l 8k   -I 1000 -w      -f $VFILE
-munmap         $OPTS -N "unmap_wu128k" -l 128k -I 50000        -w -B 10        -f $VFILE
-munmap         $OPTS -N "unmap_wa8k"   -l 8k   -I 1000 -w      -f MAP_ANON
-munmap         $OPTS -N "unmap_wa128k" -l 128k -I 10000        -w      -f MAP_ANON
-
-
-mprotect       $OPTS -N "mprot_z8k"    -l 8k  -I 300                   -f /dev/zero
-mprotect       $OPTS -N "mprot_z128k"  -l 128k -I 500          -f /dev/zero
-mprotect       $OPTS -N "mprot_wz8k"   -l 8k   -I 500  -w      -f /dev/zero
-mprotect       $OPTS -N "mprot_wz128k" -l 128k -I 1000 -w      -f /dev/zero
-mprotect       $OPTS -N "mprot_twz8k"  -l 8k   -I 1000 -w -t   -f /dev/zero
-mprotect       $OPTS -N "mprot_tw128k" -l 128k -I 2000 -w -t   -f /dev/zero
-mprotect       $OPTS -N "mprot_tw4m"   -l 4m   -w -t -B 1  -f /dev/zero
-
-pipe           $OPTS -N "pipe_pst1"    -s 1    -I 1000 -x pipe -m st
-pipe           $OPTS -N "pipe_pmt1"    -s 1    -I 8000 -x pipe -m mt
-pipe           $OPTS -N "pipe_pmp1"    -s 1    -I 8000 -x pipe -m mp
-pipe           $OPTS -N "pipe_pst4k"   -s 4k   -I 1000 -x pipe -m st
-pipe           $OPTS -N "pipe_pmt4k"   -s 4k   -I 8000 -x pipe -m mt
-pipe           $OPTS -N "pipe_pmp4k"   -s 4k   -I 8000 -x pipe -m mp
-
-pipe           $OPTS -N "pipe_sst1"    -s 1    -I 1000 -x sock -m st
-pipe           $OPTS -N "pipe_smt1"    -s 1    -I 8000 -x sock -m mt
-pipe           $OPTS -N "pipe_smp1"    -s 1    -I 8000 -x sock -m mp
-pipe           $OPTS -N "pipe_sst4k"   -s 4k   -I 1000 -x sock -m st
-pipe           $OPTS -N "pipe_smt4k"   -s 4k   -I 8000 -x sock -m mt
-pipe           $OPTS -N "pipe_smp4k"   -s 4k   -I 8000 -x sock -m mp
-
-pipe           $OPTS -N "pipe_tst1"    -s 1    -I 1000 -x tcp  -m st
-pipe           $OPTS -N "pipe_tmt1"    -s 1    -I 8000 -x tcp  -m mt
-pipe           $OPTS -N "pipe_tmp1"    -s 1    -I 8000 -x tcp  -m mp
-pipe           $OPTS -N "pipe_tst4k"   -s 4k   -I 1000 -x tcp  -m st
-pipe           $OPTS -N "pipe_tmt4k"   -s 4k   -I 8000 -x tcp  -m mt
-pipe           $OPTS -N "pipe_tmp4k"   -s 4k   -I 8000 -x tcp  -m mp
-
-#connection    $OPTS -N "conn_accept"          -B 256      -a
-
-lmbench_bw_unix -B 11 -L -W
-
-lmbench_bw_mem $OPTS -N lmbench_bcopy_512 -s 512 -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_1k -s 1k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_2k -s 2k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_4k -s 4k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_8k -s 8k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_16k -s 16k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_32k -s 32k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_64k -s 64k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_128k -s 128k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_256k -s 256k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_512k -s 512k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_1m -s 1m -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bzero_512 -s 512 -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_1k -s 1k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_2k -s 2k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_4k -s 4k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_8k -s 8k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_16k -s 16k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_32k -s 32k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_64k -s 64k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_128k -s 128k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_256k -s 256k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_512k -s 512k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_1m -s 1m -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_512 -s 512 -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_1k -s 1k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_2k -s 2k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_4k -s 4k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_8k -s 8k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_16k -s 16k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_32k -s 32k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_64k -s 64k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_128k -s 128k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_256k -s 256k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_512k -s 512k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_1m -s 1m -x fcp
-lmbench_bw_mem $OPTS -N lmbench_cp_512 -s 512 -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_1k -s 1k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_2k -s 2k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_4k -s 4k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_8k -s 8k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_16k -s 16k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_32k -s 32k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_64k -s 64k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_128k -s 128k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_256k -s 256k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_512k -s 512k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_1m -s 1m -x cp
-lmbench_bw_mem $OPTS -N lmbench_frd_512 -s 512 -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_1k -s 1k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_2k -s 2k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_4k -s 4k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_8k -s 8k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_16k -s 16k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_32k -s 32k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_64k -s 64k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_128k -s 128k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_256k -s 256k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_512k -s 512k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_1m -s 1m -x frd
-lmbench_bw_mem $OPTS -N lmbench_rd_512 -s 512 -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_1k -s 1k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_2k -s 2k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_4k -s 4k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_8k -s 8k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_16k -s 16k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_32k -s 32k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_64k -s 64k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_128k -s 128k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_256k -s 256k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_512k -s 512k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_1m -s 1m -x rd
-lmbench_bw_mem $OPTS -N lmbench_fwr_512 -s 512 -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_1k -s 1k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_2k -s 2k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_4k -s 4k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_8k -s 8k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_16k -s 16k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_32k -s 32k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_64k -s 64k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_128k -s 128k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_256k -s 256k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_512k -s 512k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_1m -s 1m -x fwr
-lmbench_bw_mem $OPTS -N lmbench_wr_512 -s 512 -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_1k -s 1k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_2k -s 2k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_4k -s 4k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_8k -s 8k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_16k -s 16k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_32k -s 32k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_64k -s 64k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_128k -s 128k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_256k -s 256k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_512k -s 512k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_1m -s 1m -x wr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_512 -s 512 -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_1k -s 1k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_2k -s 2k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_4k -s 4k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_8k -s 8k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_16k -s 16k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_32k -s 32k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_64k -s 64k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_128k -s 128k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_256k -s 256k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_512k -s 512k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_1m -s 1m -x rdwr
-
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_512 -s 512 -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_1k -s 1k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_2k -s 2k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_4k -s 4k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_8k -s 8k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_16k -s 16k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_32k -s 32k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_64k -s 64k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_128k -s 128k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_256k -s 256k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_512k -s 512k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_1m -s 1m -f $TFILE
-
-.
diff --git a/tools/tests/libMicro/benchDS.sh b/tools/tests/libMicro/benchDS.sh
deleted file mode 100755 (executable)
index cb58300..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-#!/bin/sh
-#
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-function usage {
-    echo "Usage"
-    echo "$0 [-l] [-h] <#-of-users> nodename [test match pattern]"
-    echo "-l                    : disable libinfo L1 cache"
-    echo "-h                    : Help. This option displays information on how to run the script. "
-    echo "[test match pattern]  : This option runs only the test that is specified"
-    echo                                                                                                                                                                                                       
-    echo "You must have set up users, groups, and SACLs with od_account_create"
-    echo "with the same number of user accounts."                                                                                                                                                               
-    echo "Supply a pattern to match to run a subset of tests"
-    exit 1
-}
-
-# default to libinfo cache enabled
-L1CACHE="1"
-
-while getopts "lh" OPT_LIST
-do
-    case $OPT_LIST in 
-        l) L1CACHE="0";;    # to run the libmicro tests with l1cache disabled
-        h) usage;;
-        *) usage;;
-    esac
-done
-
-shift `expr $OPTIND - 1`
-
-if [ $# -lt 2 -o $# -gt 3 ]; then
-    usage
-fi
-
-tattle="./tattle"
-
-bench_version=0.4.0
-libmicro_version=`$tattle -V`
-
-case $libmicro_version in
-$bench_version)
-       ;;
-*)
-       echo "ERROR: libMicro version doesn't match 'bench' script version"
-       exit 1
-esac
-
-TMPROOT=/private/tmp/libmicro.$$
-VARROOT=/private/var/tmp/libmicro.$$
-mkdir -p $TMPROOT
-mkdir -p $VARROOT
-trap "rm -rf $TMPROOT $VARROOT && exit" 0 2
-
-TFILE=$TMPROOT/data
-IFILE=$TMPROOT/ifile
-TDIR1=$TMPROOT/0/1/2/3/4/5/6/7/8/9
-TDIR2=$TMPROOT/1/2/3/4/5/6/7/8/9/0
-VFILE=$VARROOT/data
-VDIR1=$VARROOT/0/1/2/3/4/5/6/7/8/9
-VDIR2=$VARROOT/1/2/3/4/5/6/7/8/9/0
-
-OPTS="-E -C 200 -L -S -W"
-
-dd if=/dev/zero of=$TFILE bs=1024k count=10 2>/dev/null
-dd if=/dev/zero of=$VFILE bs=1024k count=10 2>/dev/null
-mkdir -p $TDIR1 $TDIR2
-mkdir -p $VDIR1 $VDIR2
-
-touch $IFILE
-/usr/bin/touch /private/var/tmp/lmbench
-
-
-# produce benchmark header for easier comparisons
-
-hostname=`uname -n`
-
-if [ -f /usr/sbin/psrinfo ]; then
-       p_count=`psrinfo|wc -l`
-       p_mhz=`psrinfo -v | awk '/operates/{print $6 "MHz"; exit }'`
-       p_type=`psrinfo -vp 2>/dev/null | awk '{if (NR == 3) {print $0; exit}}'` 
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-fi
-
-if [ -f /proc/cpuinfo ]; then
-       p_count=`egrep processor /proc/cpuinfo | wc -l`
-       p_mhz=`awk -F: '/cpu MHz/{printf("%5.0f00Mhz\n",$2/100); exit}' /proc/cpuinfo`
-       p_type=`awk -F: '/model name/{print $2; exit}' /proc/cpuinfo`
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-else
-## Mac OS X specific stuff
-# first, get ugly output, in case pretty output isn't available
-#
-       p_count=`sysctl -n hw.physicalcpu`
-       p_mhz=`sysctl -n hw.cpufrequency`
-       p_type=`sysctl -n hw.model`
-
-if [ -x /usr/sbin/system_profiler ]; then
-       # <rdar://4655981> requires this hunk of work-around
-       # grep the XML for the characteristic we need. The key appears twice, so grep for the useful key (with 'string')
-       # use sed to strip off the <string></string> and the tabs in front of the string.  So much work for so little result.
-       #
-               p_mhz=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 current_processor_speed | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-               p_type=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 cpu_type | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-fi
-
-# look for en0 (usually ethernet) if that isn't there try en1 (usually wireless) else give up
-       p_ipaddr=`ipconfig getpacket en0 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       if [ ! $p_ipaddr  ]; then
-               p_ipaddr=`ipconfig getpacket en1 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       elif [ ! $p_ipaddr ]; then
-               p_ipaddr="unknown"
-       fi
-fi
-
-printf "\n\n!Libmicro_#:   %30s\n" $libmicro_version
-printf "!Options:      %30s\n" "$OPTS"
-printf "!Machine_name: %30s\n" "$hostname"
-printf "!OS_name:      %30s\n" `uname -s`
-printf "!OS_release:   %30s\n" `sw_vers -productVersion`
-printf "!OS_build:     %30.18s\n" "`sw_vers -buildVersion`"
-printf "!Processor:    %30s\n" `arch`
-printf "!#CPUs:        %30s\n" $p_count
-printf "!CPU_MHz:      %30s\n" "$p_mhz"
-printf "!CPU_NAME:     %30s\n" "$p_type"
-printf "!IP_address:   %30s\n" "$p_ipaddr"
-printf "!Run_by:       %30s\n" $LOGNAME
-printf "!Date:        %30s\n" "`date '+%D %R'`"
-printf "!Compiler:     %30s\n" `$tattle -c`
-printf "!Compiler Ver.:%30s\n" "`$tattle -v`"
-printf "!sizeof(long): %30s\n" `$tattle -s`
-printf "!extra_CFLAGS: %30s\n" "`$tattle -f`"
-printf "!TimerRes:     %30s\n\n\n" "`$tattle -r`"
-bin_dir="$TMPROOT/bin"
-
-mkdir -p $bin_dir
-cp bin-*/exec_bin $bin_dir/$A
-
-cp ./apple/bin-*/posix_spawn_bin $bin_dir/$A
-
-newline=0
-
-# We commonly want to adjust this script for the number of users
-# and configuration of the accounts and configuration being tested.
-#
-# Users:
-NUSERS=$1
-NODENAME=$2
-UID_BASE=5000
-UID_END=`expr $UID_BASE + $NUSERS - 1`
-USER_PREFIX=od_test_
-#
-# Groups:
-GID_ALL_USERS=1211
-GID_NO_USERS=1212
-GROUP_BASE=od_test_group
-#
-# getaddrinfo on hosts:
-HOST_BASE=sfs0
-HOST_RANGE=1-8
-
-#
-# Everything below the while loop is input for the while loop if
-# you have any tests which can't run in the while loop, put
-# them above this comment
-#
-while read A B
-do
-       # $A contains the command, $B contains the arguments
-       # we echo blank lines and comments
-       # we skip anything which fails to match *$1* (useful if
-       # we only want to test one case, but a nasty hack)
-
-       case $A in
-       \#*)
-               echo "$A $B"
-               newline=1
-               continue
-               ;;
-       
-       "")
-               if [ $newline -eq 1 ]
-               then
-                       newline=0
-                       echo
-                       echo
-               fi
-
-               continue
-               ;;
-
-       *$3*)
-               ;;
-
-       *)
-               continue
-               ;;
-       esac
-
-       if [ ! -f $bin_dir/$A ]
-       then
-               cp bin-*/$A $bin_dir/$A
-       fi
-
-       echo
-
-       (cd $TMPROOT && eval "bin/$A $B")
-
-       echo
-       echo
-done <<.
-
-# -P <# procs>
-# -T <# threads> - exclusive!
-
-# mbr_check_service_membership()
-mbr_check_service_membership   $OPTS -N "mbr_check_service_membership" -s libMicro -u ${USER_PREFIX} -r ${NUSERS}
-mbr_check_service_membership   $OPTS -N "mbr_check_service_membership_t2" -T 2 -s libMicro -u ${USER_PREFIX} -r ${NUSERS}
-mbr_check_service_membership   $OPTS -N "mbr_check_service_membership_t4" -T 4 -s libMicro -u ${USER_PREFIX} -r ${NUSERS}
-mbr_check_service_membership   $OPTS -N "mbr_check_service_membership_p2" -P 2 -s libMicro -u ${USER_PREFIX} -r ${NUSERS}
-mbr_check_service_membership   $OPTS -N "mbr_check_service_membership_p4" -P 4 -s libMicro -u ${USER_PREFIX} -r ${NUSERS}
-
-# getpwnam()
-getpwnam                       $OPTS -N "getpwnam" -l ${L1CACHE} -r ${NUSERS} -u ${USER_PREFIX}
-getpwnam                       $OPTS -N "getpwnam_t2" -T 2 -l ${L1CACHE} -r ${NUSERS} -u ${USER_PREFIX}
-getpwnam                       $OPTS -N "getpwnam_p2" -P 2 -l ${L1CACHE} -r ${NUSERS} -u ${USER_PREFIX}
-
-# mbr_check_membership()
-mbr_check_membership           $OPTS -N "mbr_check_membership" -u ${UID_BASE}-${UID_END} -g ${GID_ALL_USERS}-${GID_NO_USERS}
-mbr_check_membership           $OPTS -N "mbr_check_membership_t2" -u ${UID_BASE}-${UID_END} -g ${GID_ALL_USERS}-${GID_NO_USERS} -T 2
-mbr_check_membership           $OPTS -N "mbr_check_membership_t4" -u ${UID_BASE}-${UID_END} -g ${GID_ALL_USERS}-${GID_NO_USERS} -T 4
-mbr_check_membership           $OPTS -N "mbr_check_membership_p2" -u ${UID_BASE}-${UID_END} -g ${GID_ALL_USERS}-${GID_NO_USERS} -P 2
-mbr_check_membership           $OPTS -N "mbr_check_membership_p4" -u ${UID_BASE}-${UID_END} -g ${GID_ALL_USERS}-${GID_NO_USERS} -P 4
-
-# getpwuid()
-getpwuid                       $OPTS -N "getpwuid" -l ${L1CACHE} -u ${UID_BASE}-${UID_END}
-getpwuid                       $OPTS -N "getpwuid_t2" -l ${L1CACHE} -u ${UID_BASE}-${UID_END} -T 2
-getpwuid                       $OPTS -N "getpwuid_t4" -l ${L1CACHE} -u ${UID_BASE}-${UID_END} -T 4
-getpwuid                       $OPTS -N "getpwuid_p2" -l ${L1CACHE} -u ${UID_BASE}-${UID_END} -P 2
-getpwuid                       $OPTS -N "getpwuid_p4" -l ${L1CACHE} -u ${UID_BASE}-${UID_END} -P 4
-
-# getgrgid()
-getgrgid                       $OPTS -N "getgrgid" -l ${L1CACHE} -g ${GID_ALL_USERS}-${GID_NO_USERS}
-getgrgid                       $OPTS -N "getgrgid_t2" -l ${L1CACHE} -g ${GID_ALL_USERS}-${GID_NO_USERS} -T 2
-getgrgid                       $OPTS -N "getgrgid_t4" -l ${L1CACHE} -g ${GID_ALL_USERS}-${GID_NO_USERS} -T 4
-getgrgid                       $OPTS -N "getgrgid_p2" -l ${L1CACHE} -g ${GID_ALL_USERS}-${GID_NO_USERS} -P 2
-getgrgid                       $OPTS -N "getgrgid_p4" -l ${L1CACHE} -g ${GID_ALL_USERS}-${GID_NO_USERS} -P 4
-
-# getpwent()
-getpwent                       $OPTS -N "getpwent" -l ${L1CACHE} 
-getpwent                       $OPTS -N "getpwent_t2" -l ${L1CACHE} -T 2
-getpwent                       $OPTS -N "getpwent_t4" -l ${L1CACHE} -T 4
-getpwent                       $OPTS -N "getpwent_p2" -l ${L1CACHE} -P 2
-getpwent                       $OPTS -N "getpwent_p4" -l ${L1CACHE} -P 4
-
-# getgrent()
-getgrent                       $OPTS -N "getgrent" -l ${L1CACHE} 
-getgrent                       $OPTS -N "getgrent_t2" -l ${L1CACHE} -T 2
-getgrent                       $OPTS -N "getgrent_t4" -l ${L1CACHE} -T 4
-getgrent                       $OPTS -N "getgrent_p2" -l ${L1CACHE} -P 2
-getgrent                       $OPTS -N "getgrent_p4" -l ${L1CACHE} -P 4
-
-# getaddrinfo() host
-#getaddrinfo_host              $OPTS -N "getaddrinfo_host" -r ${HOST_RANGE} -h ${HOST_BASE}%d
-#getaddrinfo_host              $OPTS -N "getaddrinfo_host_t2" -r ${HOST_RANGE} -h ${HOST_BASE}%d -T 2
-#getaddrinfo_host              $OPTS -N "getaddrinfo_host_t4" -r ${HOST_RANGE} -h ${HOST_BASE}%d -T 4
-#getaddrinfo_host              $OPTS -N "getaddrinfo_host_p2" -r ${HOST_RANGE} -h ${HOST_BASE}%d -P 2
-#getaddrinfo_host              $OPTS -N "getaddrinfo_host_p4" -r ${HOST_RANGE} -h ${HOST_BASE}%d -P 4
-
-# getaddrinfo() port
-getaddrinfo_port               $OPTS -N "getaddrinfo_port" -l ${L1CACHE} 
-getaddrinfo_port               $OPTS -N "getaddrinfo_port_t2" -l ${L1CACHE} -T 2
-getaddrinfo_port               $OPTS -N "getaddrinfo_port_t4" -l ${L1CACHE} -T 4
-getaddrinfo_port               $OPTS -N "getaddrinfo_port_p2" -l ${L1CACHE} -P 2
-getaddrinfo_port               $OPTS -N "getaddrinfo_port_p4" -l ${L1CACHE} -P 4
-
-# getgrnam()
-getgrnam                       $OPTS -N "getgrnam" -l ${L1CACHE} -g ${GROUP_BASE} -r 2
-getgrnam                       $OPTS -N "getgrnam_t2" -l ${L1CACHE} -T 2 -g ${GROUP_BASE} -r 2
-getgrnam                       $OPTS -N "getgrnam_t4" -l ${L1CACHE} -T 4 -g ${GROUP_BASE} -r 2
-getgrnam                       $OPTS -N "getgrnam_p2" -l ${L1CACHE} -P 2 -g ${GROUP_BASE} -r 2
-getgrnam                       $OPTS -N "getgrnam_p4" -l ${L1CACHE} -P 4 -g ${GROUP_BASE} -r 2
-
-# ODQueryCreateWithNode()
-od_query_create_with_node      $OPTS -N "ODQueryCreateWithNode_cache_${NUSERS}u" -c 50 -r ${NUSERS} -t u -B 50 -n ${NODENAME}
-od_query_create_with_node      $OPTS -N "ODQueryCreateWithNode_cache_${NUSERS}u_t2" -T 2 -c 50 -r ${NUSERS} -t u -B 50 -n ${NODENAME}
-od_query_create_with_node      $OPTS -N "ODQueryCreateWithNode_cache_${NUSERS}u_t4" -T 4 -c 50 -r ${NUSERS} -t u -B 50 -n ${NODENAME}
-od_query_create_with_node      $OPTS -N "ODQueryCreateWithNode_cache_${NUSERS}u_p2" -P 2 -c 50 -r ${NUSERS} -t u -B 50 -n ${NODENAME}
-od_query_create_with_node      $OPTS -N "ODQueryCreateWithNode_cache_${NUSERS}u_p4" -P 4 -c 50 -r ${NUSERS} -t u -B 50 -n ${NODENAME}
-
-.
diff --git a/tools/tests/libMicro/benchmark_fini.c b/tools/tests/libMicro/benchmark_fini.c
deleted file mode 100644 (file)
index 4952a9a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_fini
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_fini()
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_finibatch.c b/tools/tests/libMicro/benchmark_finibatch.c
deleted file mode 100644 (file)
index 482258c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_finibatch
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-/*ARGSUSED*/
-int
-benchmark_finibatch(void *tsd)
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_finirun.c b/tools/tests/libMicro/benchmark_finirun.c
deleted file mode 100644 (file)
index 52a5822..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_finirun
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_finiworker.c b/tools/tests/libMicro/benchmark_finiworker.c
deleted file mode 100644 (file)
index 53161ea..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_finiworker
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-/*ARGSUSED*/
-int
-benchmark_finiworker(void *tsd)
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_init.c b/tools/tests/libMicro/benchmark_init.c
deleted file mode 100644 (file)
index 83cec2b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_init
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_initbatch.c b/tools/tests/libMicro/benchmark_initbatch.c
deleted file mode 100644 (file)
index 0a8cddd..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_initbatch
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_initrun.c b/tools/tests/libMicro/benchmark_initrun.c
deleted file mode 100644 (file)
index ac437d4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_initrun
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_initworker.c b/tools/tests/libMicro/benchmark_initworker.c
deleted file mode 100644 (file)
index 29b487c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_initworker
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-/*ARGSUSED*/
-int
-benchmark_initworker(void *tsd)
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_optswitch.c b/tools/tests/libMicro/benchmark_optswitch.c
deleted file mode 100644 (file)
index d46ee2f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_optswitch
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       return (0);
-}
diff --git a/tools/tests/libMicro/benchmark_result.c b/tools/tests/libMicro/benchmark_result.c
deleted file mode 100644 (file)
index c8ab2f2..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * default implementation (nop) of benchmark_result
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-char *
-benchmark_result()
-{
-       static char             result = '\0';
-
-       return (&result);
-}
diff --git a/tools/tests/libMicro/bind.c b/tools/tests/libMicro/bind.c
deleted file mode 100644 (file)
index bd8e43b..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark for bind... keep in mind tcp hash chain effects
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-#define        FIRSTPORT               12345
-
-typedef struct {
-       int                     *ts_lsns;
-       struct sockaddr_in      *ts_adds;
-} tsd_t;
-
-static int optz = -0;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-       (void) sprintf(lm_optstr, "z");
-
-       (void) sprintf(lm_usage,
-           "           [-z bind to port 0 rather than seq. number\n"
-           "notes: measures bind() on TCP");
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(lm_optB * lm_optT + 10);
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'z':
-               optz = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j;
-       int                     opt = 1;
-       struct hostent          *host;
-       int                     errors = 0;
-
-       ts->ts_lsns = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_lsns == NULL)
-               errors ++;
-
-       ts->ts_adds = (struct sockaddr_in *)malloc(lm_optB *
-           sizeof (struct sockaddr_in));
-       if (ts->ts_adds == NULL)
-               errors ++;
-
-       j = FIRSTPORT;
-       for (i = 0; i < lm_optB; i++) {
-               if ((ts->ts_lsns[i] = socket(PF_INET, SOCK_STREAM, 0)) == -1)
-                       errors ++;
-
-               if (setsockopt(ts->ts_lsns[i], SOL_SOCKET, SO_REUSEADDR,
-                   &opt, sizeof (int)) == -1)
-                       errors ++;
-
-               if ((host = gethostbyname("localhost")) == NULL)
-                       errors ++;
-
-               (void) memset(&ts->ts_adds[i], 0,
-                   sizeof (struct sockaddr_in));
-               ts->ts_adds[i].sin_family = AF_INET;
-               ts->ts_adds[i].sin_port = (optz ? 0 : htons(j++));
-               (void) memcpy(&ts->ts_adds[i].sin_addr.s_addr,
-                   host->h_addr_list[0], sizeof (struct in_addr));
-       }
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if ((bind(ts->ts_lsns[i],
-                   (struct sockaddr *)&ts->ts_adds[i],
-                   sizeof (struct sockaddr_in)) != 0) &&
-                   (errno != EADDRINUSE))
-                       res->re_errors ++;
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++)
-               (void) close(ts->ts_lsns[i]);
-       return (0);
-}
diff --git a/tools/tests/libMicro/cachetocache.c b/tools/tests/libMicro/cachetocache.c
deleted file mode 100644 (file)
index ffe9ddf..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * routine to benchmark cache-to-cache transfer times... uses
- * solaris features to find and bind to cpus in the current
- * processor set, so not likely to work elsewhere.
- */
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/processor.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/pset.h>
-
-#include "libmicro.h"
-
-static long                    opts = 1024*512;
-
-typedef struct {
-       long                    **ts_data;
-       long                    ts_result;
-       pthread_mutex_t         ts_lock;
-} tsd_t;
-
-static unsigned int ncpu = 1024;
-
-static tsd_t *thread_data[1024];
-static processorid_t cpus[1024];
-
-int traverse_ptrchain(long **, int, int);
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:");
-
-       (void) sprintf(lm_usage,
-           "       [-s size] size of access area in bytes"
-           " (default %ld)\n"
-           "notes: measures cache to cache transfer times on Solaris\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 's':
-               opts = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       if (pset_info(PS_MYID, NULL, &ncpu, cpus) < 0) {
-               perror("pset_info");
-               return (1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int i, j;
-       processorid_t cpu;
-
-       ts->ts_data = malloc(opts);
-
-       if (ts->ts_data == NULL) {
-               return (1);
-       }
-
-       (void) pthread_mutex_init(&ts->ts_lock, NULL);
-
-
-       if (processor_bind(P_LWPID, P_MYID,
-           cpu = cpus[(pthread_self() - 1) % ncpu],
-           NULL) < 0) {
-               perror("processor_bind:");
-               return (1);
-       }
-
-       (void) printf("# thread %d using processor %d\n", pthread_self(), cpu);
-
-       /*
-        * use lmbench style backwards stride
-        */
-
-       for (i = 0; i < opts / sizeof (long); i++) {
-               j = i - 128;
-               if (j < 0)
-                       j = j + opts / sizeof (long);
-               ts->ts_data[i] = (long *)&(ts->ts_data[j]);
-       }
-
-       thread_data[pthread_self() - 1] = ts;
-
-       return (0);
-}
-
-/*
- * here we go in order for each thread, causing inherent serialization
- * this is normally not a good idea, but in this case we're trying to
- * measure cache-to-cache transfer times, and if we run threads in
- * parallel we're likely to see saturation effects rather than cache-to-cache,
- * esp. on wimpy memory platforms like P4.
- */
-
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts;
-       int                     i, j;
-       int                     count = opts / 128 / sizeof (long);
-
-       for (j = 0; j < lm_optB; j++)
-               for (i = 0; i < lm_optT; i++) {
-                       ts = thread_data[i];
-                       (void) pthread_mutex_lock(&ts->ts_lock);
-                       ts->ts_result += traverse_ptrchain(
-                           (long **)ts->ts_data, count, 0);
-                       (void) pthread_mutex_unlock(&ts->ts_lock);
-               }
-
-       res->re_count = lm_optB * lm_optT * count;
-
-       return (0);
-}
-
-int
-traverse_ptrchain(long **ptr, int count, int value)
-{
-       int i;
-
-       for (i = 0; i < count; i += 10) {
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-               ptr = (long **)*ptr;
-               *ptr = *ptr + value;
-       }
-       return ((int)*ptr); /* bogus return */
-}
-
-
-char *
-benchmark_result()
-{
-       static char  result[256];
-
-       (void) sprintf(result, "%8ld ", opts);
-
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/cascade_cond.c b/tools/tests/libMicro/cascade_cond.c
deleted file mode 100644 (file)
index 350e3d6..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The "cascade" test case is a multiprocess/multithread batten-passing model
- * using lock primitives alone for synchronisation. Threads are arranged in a
- * ring. Each thread has two locks of its own on which it blocks, and is able
- * to manipulate the two locks belonging to the thread which follows it in the
- * ring.
- *
- * The number of threads (nthreads) is specified by the generic libMicro -P/-T
- * options. With nthreads == 1 (the default) the uncontended case can be timed.
- *
- * The main logic is generic and allows any simple blocking API to be tested.
- * The API-specific component is clearly indicated.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <sys/mman.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     ts_id;
-       int                     ts_us0;         /* our lock indices */
-       int                     ts_us1;
-       int                     ts_them0;       /* their lock indices */
-       int                     ts_them1;
-} tsd_t;
-
-static int                     nthreads;
-
-/*
- * API-specific code BEGINS here
- */
-
-static int                     opto = 0;
-static int                     opts = 0;
-static int                     nlocks;
-static pthread_mutex_t *mxs;
-static pthread_cond_t          *cvs;
-static int                     *conds;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "os");
-
-       lm_defN = "cscd_cond";
-
-       (void) sprintf(lm_usage,
-           "       [-o] (do signal outside mutex)\n"
-           "       [-s] (force PTHREAD_PROCESS_SHARED)\n"
-           "notes: thread cascade using pthread_conds\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'o':
-               opto = 1;
-               break;
-       case 's':
-               opts = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     i;
-       int                     e = 0;
-       pthread_mutexattr_t     ma;
-       pthread_condattr_t      ca;
-
-       nthreads = lm_optP * lm_optT;
-       nlocks = nthreads * 2;
-       /*LINTED*/
-       mxs = (pthread_mutex_t *)mmap(NULL,
-           nlocks * sizeof (pthread_mutex_t),
-           PROT_READ | PROT_WRITE,
-           MAP_ANON | MAP_SHARED,
-           -1, 0L);
-       if (mxs == MAP_FAILED) {
-               return (1);
-       }
-
-       /*LINTED*/
-       cvs = (pthread_cond_t *)mmap(NULL,
-           nlocks * sizeof (pthread_cond_t),
-           PROT_READ | PROT_WRITE,
-           MAP_ANON | MAP_SHARED,
-           -1, 0L);
-       if (cvs == MAP_FAILED) {
-               return (1);
-       }
-
-       /*LINTED*/
-       conds = (int *)mmap(NULL,
-           nlocks * sizeof (pthread_cond_t),
-           PROT_READ | PROT_WRITE,
-           MAP_ANON | MAP_SHARED,
-           -1, 0L);
-       if (conds == MAP_FAILED) {
-               return (1);
-       }
-
-       (void) pthread_mutexattr_init(&ma);
-       (void) pthread_condattr_init(&ca);
-       if (lm_optP > 1 || opts) {
-               (void) pthread_mutexattr_setpshared(&ma,
-                   PTHREAD_PROCESS_SHARED);
-               (void) pthread_condattr_setpshared(&ca,
-                   PTHREAD_PROCESS_SHARED);
-       } else {
-               (void) pthread_mutexattr_setpshared(&ma,
-                   PTHREAD_PROCESS_PRIVATE);
-               (void) pthread_condattr_setpshared(&ca,
-                   PTHREAD_PROCESS_PRIVATE);
-       }
-
-       for (i = 0; i < nlocks; i++) {
-               (void) pthread_mutex_init(&mxs[i], &ma);
-               (void) pthread_cond_init(&cvs[i], &ca);
-               conds[i] = 0;
-       }
-
-       return (e);
-}
-
-int
-block(int index)
-{
-       (void) pthread_mutex_lock(&mxs[index]);
-       while (conds[index] != 0) {
-               (void) pthread_cond_wait(&cvs[index], &mxs[index]);
-       }
-       conds[index] = 1;
-       (void) pthread_mutex_unlock(&mxs[index]);
-
-       return (0);
-}
-
-int
-unblock(int index)
-{
-       (void) pthread_mutex_lock(&mxs[index]);
-       conds[index] = 0;
-       if (opto) {
-               (void) pthread_mutex_unlock(&mxs[index]);
-               (void) pthread_cond_signal(&cvs[index]);
-       } else {
-               (void) pthread_cond_signal(&cvs[index]);
-               (void) pthread_mutex_unlock(&mxs[index]);
-       }
-       return (0);
-}
-
-/*
- * API-specific code ENDS here
- */
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     e = 0;
-
-       if (ts->ts_once == 0) {
-               int             us, them;
-
-#if !defined(__APPLE__)
-        us = (getpindex() * lm_optT) + gettindex();
-#else
-        us = gettsdindex(tsd);
-#endif /* __APPLE__ */
-       
-               them = (us + 1) % (lm_optP * lm_optT);
-
-               ts->ts_id = us;
-
-               /* lock index asignment for us and them */
-               ts->ts_us0 = (us * 2);
-               ts->ts_us1 = (us * 2) + 1;
-               if (us < nthreads - 1) {
-                       /* straight-thru connection to them */
-                       ts->ts_them0 = (them * 2);
-                       ts->ts_them1 = (them * 2) + 1;
-               } else {
-                       /* cross-over connection to them */
-                       ts->ts_them0 = (them * 2) + 1;
-                       ts->ts_them1 = (them * 2);
-               }
-
-               ts->ts_once = 1;
-       }
-
-       /* block their first move */
-       e += block(ts->ts_them0);
-
-       return (e);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     e = 0;
-
-       /* wait to be unblocked (id == 0 will not block) */
-       e += block(ts->ts_us0);
-
-       for (i = 0; i < lm_optB; i += 2) {
-               /* allow them to block us again */
-               e += unblock(ts->ts_us0);
-
-               /* block their next + 1 move */
-               e += block(ts->ts_them1);
-
-               /* unblock their next move */
-               e += unblock(ts->ts_them0);
-
-               /* wait for them to unblock us */
-               e += block(ts->ts_us1);
-
-               /* repeat with locks reversed */
-               e += unblock(ts->ts_us1);
-               e += block(ts->ts_them0);
-               e += unblock(ts->ts_them1);
-               e += block(ts->ts_us0);
-       }
-
-       /* finish batch with nothing blocked */
-       e += unblock(ts->ts_them0);
-       e += unblock(ts->ts_us0);
-
-       res->re_count = i;
-       res->re_errors = e;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/cascade_fcntl.c b/tools/tests/libMicro/cascade_fcntl.c
deleted file mode 100644 (file)
index b9bde5d..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The "cascade" test case is a multiprocess/multithread batten-passing model
- * using lock primitives alone for synchronisation. Threads are arranged in a
- * ring. Each thread has two locks of its own on which it blocks, and is able
- * to manipulate the two locks belonging to the thread which follows it in the
- * ring.
- *
- * The number of threads (nthreads) is specified by the generic libMicro -P/-T
- * options. With nthreads == 1 (the default) the uncontended case can be timed.
- *
- * The main logic is generic and allows any simple blocking API to be tested.
- * The API-specific component is clearly indicated.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     ts_id;
-       int                     ts_us0;         /* our lock indices */
-       int                     ts_us1;
-       int                     ts_them0;       /* their lock indices */
-       int                     ts_them1;
-} tsd_t;
-
-static int                     nthreads;
-
-/*
- * API-specific code BEGINS here
- */
-
-#define        DEFD                    "/private/tmp"
-
-static char                    *optd = DEFD;
-static int                     file;
-static int                     nlocks;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "d:");
-
-       lm_defN = "cscd_fcntl";
-
-       (void) sprintf(lm_usage,
-           "       [-d directory for temp file (default %s)]\n"
-           "notes: thread cascade using fcntl region locking\n",
-           DEFD);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'd':
-               optd = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     errors = 0;
-       char                    fname[1024];
-
-       nthreads = lm_optP * lm_optT;
-       nlocks = nthreads * 2;
-
-       (void) sprintf(fname, "%s/cascade.%ld", optd, getpid());
-
-       file = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600);
-       if (file == -1) {
-               errors++;
-       }
-
-       if (unlink(fname)) {
-               errors++;
-       }
-
-       if (ftruncate(file, nlocks * 3) == -1) {
-               errors++;
-       }
-
-       return (errors);
-}
-
-int
-block(int index)
-{
-       struct flock            fl;
-
-       fl.l_type = F_WRLCK;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = index;
-       fl.l_len = 1;
-       return (fcntl(file, F_SETLKW, &fl) == -1);
-}
-
-int
-unblock(int index)
-{
-       struct flock            fl;
-
-       fl.l_type = F_UNLCK;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = index;
-       fl.l_len = 1;
-       return (fcntl(file, F_SETLK, &fl) == -1);
-}
-
-/*
- * API-specific code ENDS here
- */
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     e = 0;
-
-       if (ts->ts_once == 0) {
-               int             us, them;
-
-#if !defined(__APPLE__)
-        us = (getpindex() * lm_optT) + gettindex();
-#else
-        us = gettsdindex(tsd);
-#endif /* __APPLE__ */
-       
-               them = (us + 1) % (lm_optP * lm_optT);
-
-               ts->ts_id = us;
-
-               /* lock index asignment for us and them */
-               ts->ts_us0 = (us * 4);
-               ts->ts_us1 = (us * 4) + 2;
-               if (us < nthreads - 1) {
-                       /* straight-thru connection to them */
-                       ts->ts_them0 = (them * 4);
-                       ts->ts_them1 = (them * 4) + 2;
-               } else {
-                       /* cross-over connection to them */
-                       ts->ts_them0 = (them * 4) + 2;
-                       ts->ts_them1 = (them * 4);
-               }
-
-               ts->ts_once = 1;
-       }
-
-       /* block their first move */
-       e += block(ts->ts_them0);
-
-       return (e);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     e = 0;
-
-       /* wait to be unblocked (id == 0 will not block) */
-       e += block(ts->ts_us0);
-
-       for (i = 0; i < lm_optB; i += 2) {
-               /* allow them to block us again */
-               e += unblock(ts->ts_us0);
-
-               /* block their next + 1 move */
-               e += block(ts->ts_them1);
-
-               /* unblock their next move */
-               e += unblock(ts->ts_them0);
-
-               /* wait for them to unblock us */
-               e += block(ts->ts_us1);
-
-               /* repeat with locks reversed */
-               e += unblock(ts->ts_us1);
-               e += block(ts->ts_them0);
-               e += unblock(ts->ts_them1);
-               e += block(ts->ts_us0);
-       }
-
-       /* finish batch with nothing blocked */
-       e += unblock(ts->ts_them0);
-       e += unblock(ts->ts_us0);
-
-       res->re_count = i;
-       res->re_errors = e;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/cascade_flock.c b/tools/tests/libMicro/cascade_flock.c
deleted file mode 100644 (file)
index e225b40..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The "cascade" test case is a multiprocess/multithread batten-passing model
- * using lock primitives alone for synchronisation. Threads are arranged in a
- * ring. Each thread has two locks of its own on which it blocks, and is able
- * to manipulate the two locks belonging to the thread which follows it in the
- * ring.
- *
- * The number of threads (nthreads) is specified by the generic libMicro -P/-T
- * options. With nthreads == 1 (the default) the uncontended case can be timed.
- *
- * The main logic is generic and allows any simple blocking API to be tested.
- * The API-specific component is clearly indicated.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-#ifndef LOCK_EX
-#include "/usr/ucbinclude/sys/file.h"
-extern int flock(int fd, int operation);
-#endif
-
-typedef struct {
-       int                     ts_once;
-       int                     ts_id;
-       int                     ts_us0;         /* our lock indices */
-       int                     ts_us1;
-       int                     ts_them0;       /* their lock indices */
-       int                     ts_them1;
-} tsd_t;
-
-static int                     nthreads;
-
-/*
- * API-specific code BEGINS here
- */
-
-#define        DEFD                    "/private/tmp"
-
-static char                    *optd = DEFD;
-static int                     nfiles;
-static int                     *files;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "d:");
-
-       lm_defN = "cscd_flock";
-
-       (void) sprintf(lm_usage,
-           "       [-d directory for temp files (default %s)]\n"
-           "notes: thread cascade using flock file locking\n",
-           DEFD);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'd':
-               optd = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     i;
-       int                     errors = 0;
-       char                    fname[1024];
-
-       nthreads = lm_optP * lm_optT;
-       nfiles = nthreads * 2;
-       (void) setfdlimit(nfiles + 10);
-       files = (int *)malloc(nfiles * sizeof (int));
-       if (files == NULL) {
-               return (1);
-       }
-
-       (void) sprintf(fname, "%s/cascade.%ld", optd, getpid());
-
-       for (i = 0; i < nfiles; i++) {
-               files[i] = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600);
-               if (files[i] == -1) {
-                       errors++;
-               }
-               if (unlink(fname)) {
-                       errors++;
-               }
-       }
-
-       return (errors);
-}
-
-int
-block(int index)
-{
-       return (flock(files[index], LOCK_EX) == -1);
-}
-
-int
-unblock(int index)
-{
-       return (flock(files[index], LOCK_UN) == -1);
-}
-
-/*
- * API-specific code ENDS here
- */
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     e = 0;
-
-       if (ts->ts_once == 0) {
-               int             us, them;
-
-#if !defined(__APPLE__)
-        us = (getpindex() * lm_optT) + gettindex();
-#else
-        us = gettsdindex(tsd);
-#endif /* __APPLE__ */
-       
-               them = (us + 1) % (lm_optP * lm_optT);
-
-               ts->ts_id = us;
-
-               /* lock index asignment for us and them */
-               ts->ts_us0 = (us * 2);
-               ts->ts_us1 = (us * 2) + 1;
-               if (us < nthreads - 1) {
-                       /* straight-thru connection to them */
-                       ts->ts_them0 = (them * 2);
-                       ts->ts_them1 = (them * 2) + 1;
-               } else {
-                       /* cross-over connection to them */
-                       ts->ts_them0 = (them * 2) + 1;
-                       ts->ts_them1 = (them * 2);
-               }
-
-               ts->ts_once = 1;
-       }
-
-       /* block their first move */
-       e += block(ts->ts_them0);
-
-       return (e);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     e = 0;
-
-       /* wait to be unblocked (id == 0 will not block) */
-       e += block(ts->ts_us0);
-
-       for (i = 0; i < lm_optB; i += 2) {
-               /* allow them to block us again */
-               e += unblock(ts->ts_us0);
-
-               /* block their next + 1 move */
-               e += block(ts->ts_them1);
-
-               /* unblock their next move */
-               e += unblock(ts->ts_them0);
-
-               /* wait for them to unblock us */
-               e += block(ts->ts_us1);
-
-               /* repeat with locks reversed */
-               e += unblock(ts->ts_us1);
-               e += block(ts->ts_them0);
-               e += unblock(ts->ts_them1);
-               e += block(ts->ts_us0);
-       }
-
-       /* finish batch with nothing blocked */
-       e += unblock(ts->ts_them0);
-       e += unblock(ts->ts_us0);
-
-       res->re_count = i;
-       res->re_errors = e;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/cascade_lockf.c b/tools/tests/libMicro/cascade_lockf.c
deleted file mode 100644 (file)
index 1792c09..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The "cascade" test case is a multiprocess/multithread batten-passing model
- * using lock primitives alone for synchronisation. Threads are arranged in a
- * ring. Each thread has two locks of its own on which it blocks, and is able
- * to manipulate the two locks belonging to the thread which follows it in the
- * ring.
- *
- * The number of threads (nthreads) is specified by the generic libMicro -P/-T
- * options. With nthreads == 1 (the default) the uncontended case can be timed.
- *
- * The main logic is generic and allows any simple blocking API to be tested.
- * The API-specific component is clearly indicated.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     ts_id;
-       int                     ts_us0;         /* our lock indices */
-       int                     ts_us1;
-       int                     ts_them0;       /* their lock indices */
-       int                     ts_them1;
-} tsd_t;
-
-static int                     nthreads;
-
-/*
- * API-specific code BEGINS here
- */
-
-#define        DEFD                    "/private/tmp"
-
-static char                    *optd = DEFD;
-static int                     nfiles;
-static int                     *files;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "d:");
-
-       lm_defN = "cscd_lockf";
-
-       (void) sprintf(lm_usage,
-           "       [-d directory for temp files (default %s)]\n"
-           "notes: thread cascade using lockf file locking\n",
-           DEFD);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'd':
-               optd = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     i;
-       int                     errors = 0;
-       char                    fname[1024];
-
-       nthreads = lm_optP * lm_optT;
-       nfiles = nthreads * 2;
-       (void) setfdlimit(nfiles + 10);
-       files = (int *)malloc(nfiles * sizeof (int));
-       if (files == NULL) {
-               return (1);
-       }
-
-       (void) sprintf(fname, "%s/cascade.%ld", optd, getpid());
-
-       for (i = 0; i < nfiles; i++) {
-               files[i] = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600);
-               if (files[i] == -1) {
-                       errors++;
-               }
-               if (unlink(fname)) {
-                       errors++;
-               }
-       }
-
-       return (errors);
-}
-
-int
-block(int index)
-{
-       return (lockf(files[index], F_LOCK, 0) == -1);
-}
-
-int
-unblock(int index)
-{
-       return (lockf(files[index], F_ULOCK, 0) == -1);
-}
-
-/*
- * API-specific code ENDS here
- */
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     e = 0;
-
-       if (ts->ts_once == 0) {
-               int             us, them;
-
-#if !defined(__APPLE__)
-        us = (getpindex() * lm_optT) + gettindex();
-#else
-        us = gettsdindex(tsd);
-#endif /* __APPLE__ */
-       
-               them = (us + 1) % (lm_optP * lm_optT);
-
-               ts->ts_id = us;
-
-               /* lock index asignment for us and them */
-               ts->ts_us0 = (us * 2);
-               ts->ts_us1 = (us * 2) + 1;
-               if (us < nthreads - 1) {
-                       /* straight-thru connection to them */
-                       ts->ts_them0 = (them * 2);
-                       ts->ts_them1 = (them * 2) + 1;
-               } else {
-                       /* cross-over connection to them */
-                       ts->ts_them0 = (them * 2) + 1;
-                       ts->ts_them1 = (them * 2);
-               }
-
-               ts->ts_once = 1;
-       }
-
-       /* block their first move */
-       e += block(ts->ts_them0);
-
-       return (e);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     e = 0;
-
-       /* wait to be unblocked (id == 0 will not block) */
-       e += block(ts->ts_us0);
-
-       for (i = 0; i < lm_optB; i += 2) {
-               /* allow them to block us again */
-               e += unblock(ts->ts_us0);
-
-               /* block their next + 1 move */
-               e += block(ts->ts_them1);
-
-               /* unblock their next move */
-               e += unblock(ts->ts_them0);
-
-               /* wait for them to unblock us */
-               e += block(ts->ts_us1);
-
-               /* repeat with locks reversed */
-               e += unblock(ts->ts_us1);
-               e += block(ts->ts_them0);
-               e += unblock(ts->ts_them1);
-               e += block(ts->ts_us0);
-       }
-
-       /* finish batch with nothing blocked */
-       e += unblock(ts->ts_them0);
-       e += unblock(ts->ts_us0);
-
-       res->re_count = i;
-       res->re_errors = e;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/cascade_mutex.c b/tools/tests/libMicro/cascade_mutex.c
deleted file mode 100644 (file)
index 4f58074..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The "cascade" test case is a multiprocess/multithread batten-passing model
- * using lock primitives alone for synchronisation. Threads are arranged in a
- * ring. Each thread has two locks of its own on which it blocks, and is able
- * to manipulate the two locks belonging to the thread which follows it in the
- * ring.
- *
- * The number of threads (nthreads) is specified by the generic libMicro -P/-T
- * options. With nthreads == 1 (the default) the uncontended case can be timed.
- *
- * The main logic is generic and allows any simple blocking API to be tested.
- * The API-specific component is clearly indicated.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <sys/mman.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     ts_id;
-       int                     ts_us0;         /* our lock indices */
-       int                     ts_us1;
-       int                     ts_them0;       /* their lock indices */
-       int                     ts_them1;
-} tsd_t;
-
-static int                     nthreads;
-
-/*
- * API-specific code BEGINS here
- */
-
-static int                     opts = 0;
-static int                     nlocks;
-static pthread_mutex_t *locks;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s");
-
-       lm_defN = "cscd_mutex";
-
-       (void) sprintf(lm_usage,
-           "       [-s] (force PTHREAD_PROCESS_SHARED)\n"
-           "notes: thread cascade using pthread_mutexes\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 's':
-               opts = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     i;
-       int                     e = 0;
-       pthread_mutexattr_t     ma;
-
-       nthreads = lm_optP * lm_optT;
-       nlocks = nthreads * 2;
-       /*LINTED*/
-       locks = (pthread_mutex_t *)mmap(NULL,
-           nlocks * sizeof (pthread_mutex_t),
-           PROT_READ | PROT_WRITE,
-           MAP_ANON | MAP_SHARED,
-           -1, 0L);
-       if (locks == MAP_FAILED) {
-               return (1);
-       }
-
-       (void) pthread_mutexattr_init(&ma);
-       if (lm_optP > 1 || opts) {
-               (void) pthread_mutexattr_setpshared(&ma,
-                   PTHREAD_PROCESS_SHARED);
-       } else {
-               (void) pthread_mutexattr_setpshared(&ma,
-                   PTHREAD_PROCESS_PRIVATE);
-       }
-
-       for (i = 0; i < nlocks; i++) {
-               (void) pthread_mutex_init(&locks[i], &ma);
-       }
-
-       return (e);
-}
-
-int
-block(int index)
-{
-       return (pthread_mutex_lock(&locks[index]) == -1);
-}
-
-int
-unblock(int index)
-{
-       return (pthread_mutex_unlock(&locks[index]) == -1);
-}
-
-/*
- * API-specific code ENDS here
- */
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     e = 0;
-
-       if (ts->ts_once == 0) {
-               int             us, them;
-
-#if !defined(__APPLE__)
-                us = (getpindex() * lm_optT) + gettindex();
-#else
-                us = gettsdindex(tsd);
-#endif /* __APPLE__ */
-       
-               them = (us + 1) % (lm_optP * lm_optT);
-
-               ts->ts_id = us;
-
-               /* lock index asignment for us and them */
-               ts->ts_us0 = (us * 2);
-               ts->ts_us1 = (us * 2) + 1;
-               if (us < nthreads - 1) {
-                       /* straight-thru connection to them */
-                       ts->ts_them0 = (them * 2);
-                       ts->ts_them1 = (them * 2) + 1;
-               } else {
-                       /* cross-over connection to them */
-                       ts->ts_them0 = (them * 2) + 1;
-                       ts->ts_them1 = (them * 2);
-               }
-
-               ts->ts_once = 1;
-       }
-
-       /* block their first move */
-       e += block(ts->ts_them0);
-
-       return (e);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     e = 0;
-
-       /* wait to be unblocked (id == 0 will not block) */
-       e += block(ts->ts_us0);
-
-       for (i = 0; i < lm_optB; i += 2) {
-               /* allow them to block us again */
-               e += unblock(ts->ts_us0);
-
-               /* block their next + 1 move */
-               e += block(ts->ts_them1);
-
-               /* unblock their next move */
-               e += unblock(ts->ts_them0);
-
-               /* wait for them to unblock us */
-               e += block(ts->ts_us1);
-
-               /* repeat with locks reversed */
-               e += unblock(ts->ts_us1);
-               e += block(ts->ts_them0);
-               e += unblock(ts->ts_them1);
-               e += block(ts->ts_us0);
-       }
-
-       /* finish batch with nothing blocked */
-       e += unblock(ts->ts_them0);
-       e += unblock(ts->ts_us0);
-
-       res->re_count = i;
-       res->re_errors = e;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/chdir.c b/tools/tests/libMicro/chdir.c
deleted file mode 100644 (file)
index a9ff379..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * change directory benchmark
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-#define        DEFAULTDIR              "/"
-#define        MAXPATHLEN              1024
-
-static int                     optg = 0;
-
-static int                     dircount;
-static char **                 dirlist;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_optstr, "g");
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-g] (do getcwd() also)\n"
-           "       directory ... (default = %s)\n"
-           "notes: measures chdir() and (optionally) getcwd()",
-           DEFAULTDIR);
-
-       (void) sprintf(lm_header, "%5s %5s", "dirs", "gets");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'g':
-               optg = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       extern int              optind;
-       int                     i;
-
-       dircount = lm_argc - optind;
-       if (dircount <= 0) {
-               dirlist = (char **)malloc(sizeof (char *));
-               dirlist[0] = DEFAULTDIR;
-               dircount = 1;
-       } else {
-               dirlist = (char **)malloc(dircount * sizeof (char *));
-               for (i = 0; i < dircount; i++) {
-                       dirlist[i] = lm_argv[optind++];
-               }
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i, j;
-       char                    buf[MAXPATHLEN];
-
-       j = 0;
-       for (i = 0; i < lm_optB; i++) {
-               if (chdir(dirlist[j]) == -1)
-                       res->re_errors++;
-               j++;
-               j %= dircount;
-
-               if (optg && (getcwd(buf, MAXPATHLEN) == NULL)) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%5d %5s", dircount, optg ? "y" : "n");
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/close.c b/tools/tests/libMicro/close.c
deleted file mode 100644 (file)
index 6050bcd..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark for close
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/dev/null"
-static char                    *optf = DEFF;
-static int                     optb = 0;
-
-typedef struct {
-       int                     *ts_fds;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-
-       (void) sprintf(lm_optstr, "f:b");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-close (default %s)]\n"
-           "       [-b] (try to close an unopened fd)\n"
-           "notes: measures close()",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       case 'b':
-               optb = 1;
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(lm_optB * lm_optT + 10);
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       ts->ts_fds = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_fds == NULL) {
-               return (1);
-       }
-       return (0);
-}
-
-/*
- * don't need a finiworker; we're exiting anyway
- */
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_fds[i] = ((optb == 0) ?
-                   open(optf, O_RDONLY) : i + 1024);
-               if (ts->ts_fds[i] == -1) {
-                       errors++;
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (close(ts->ts_fds[i]) == -1 && !optb) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/close_tcp.c b/tools/tests/libMicro/close_tcp.c
deleted file mode 100644 (file)
index 6bce7a7..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark to measure time to close a local tcp connection
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-#define        FIRSTPORT               12345
-
-typedef struct {
-       int                     *ts_lsns;
-       int                     *ts_accs;
-       int                     *ts_cons;
-       struct sockaddr_in      *ts_adds;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-
-       (void) sprintf(lm_usage,
-           "notes: measures close() on local TCP connections");
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(3 * lm_optB * lm_optT + 10);
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j;
-       int                     opt = 1;
-       struct hostent  *host;
-       int                     errors = 0;
-
-       ts->ts_lsns = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_lsns == NULL) {
-               errors ++;
-       }
-       ts->ts_accs = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_accs == NULL) {
-               errors ++;
-       }
-       ts->ts_cons = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_cons == NULL) {
-               errors ++;
-       }
-       ts->ts_adds = (struct sockaddr_in *)malloc(lm_optB *
-           sizeof (struct sockaddr_in));
-       if (ts->ts_adds == NULL) {
-               errors ++;
-       }
-
-       j = FIRSTPORT;
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_lsns[i] = socket(AF_INET, SOCK_STREAM, 0);
-               if (ts->ts_lsns[i] == -1) {
-                       perror("socket");
-                       errors ++;
-               }
-
-               if (setsockopt(ts->ts_lsns[i], SOL_SOCKET, SO_REUSEADDR,
-                   &opt, sizeof (int)) == -1) {
-                       perror("setsockopt");
-                       errors ++;
-               }
-
-               if ((host = gethostbyname("localhost")) == NULL) {
-                       errors ++;
-               }
-
-               for (;;) {
-                       (void) memset(&ts->ts_adds[i], 0,
-                           sizeof (struct sockaddr_in));
-                       ts->ts_adds[i].sin_family = AF_INET;
-                       ts->ts_adds[i].sin_port = htons(j++);
-                       (void) memcpy(&ts->ts_adds[i].sin_addr.s_addr,
-                           host->h_addr_list[0], sizeof (struct in_addr));
-
-                       if (bind(ts->ts_lsns[i],
-                           (struct sockaddr *)&ts->ts_adds[i],
-                           sizeof (struct sockaddr_in)) == 0) {
-                               break;
-                       }
-
-                       if (errno != EADDRINUSE) {
-                               perror("bind");
-                               errors ++;
-                       }
-               }
-
-               if (listen(ts->ts_lsns[i], 5) == -1) {
-                       perror("listen");
-                       errors ++;
-               }
-
-       }
-       return (errors);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     result;
-       struct sockaddr_in      addr;
-       socklen_t               size;
-       int                     errors = 0;
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_cons[i] = socket(AF_INET, SOCK_STREAM, 0);
-               if (ts->ts_cons[i] == -1) {
-                       perror("socket");
-                       errors ++;
-                       continue;
-               }
-
-               if (fcntl(ts->ts_cons[i], F_SETFL, O_NDELAY) == -1) {
-                       perror("fcnt");
-                       errors ++;
-                       continue;
-               }
-
-               result = connect(ts->ts_cons[i],
-                   (struct sockaddr *)&ts->ts_adds[i],
-                   sizeof (struct sockaddr_in));
-
-               if ((result == -1) && (errno != EINPROGRESS)) {
-                       perror("connect");
-                       errors ++;
-                       continue;
-               }
-
-               size = sizeof (struct sockaddr);
-               result = accept(ts->ts_lsns[i], (struct sockaddr *)&addr,
-                   &size);
-               if (result == -1) {
-                       perror("accept");
-                       errors ++;
-                       continue;
-               }
-               ts->ts_accs[i] = result;
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (close(ts->ts_accs[i]) == -1) {
-                       res->re_errors ++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) close(ts->ts_cons[i]);
-       }
-
-       return (0);
-}
-
-int
-benchmark_finiworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) close(ts->ts_lsns[i]);
-       }
-       return (0);
-}
diff --git a/tools/tests/libMicro/connection.c b/tools/tests/libMicro/connection.c
deleted file mode 100644 (file)
index 67239f9..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/poll.h>
-
-#include "libmicro.h"
-
-#define        FIRSTPORT               12345
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_lsns;
-       int                     *ts_accs;
-       int                     *ts_cons;
-       struct sockaddr_in      *ts_adds;
-} tsd_t;
-
-static int                     opta = 0;
-static int                     optc = 0;
-static struct hostent          *host;
-
-int
-benchmark_init()
-{
-       lm_defB = 256;
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "ac");
-
-       (void) sprintf(lm_usage,
-           "       [-a] (measure accept() only)\n"
-           "       [-c] (measure connect() only)\n"
-           "notes: measures connect()/accept()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'a':
-               opta = 1;
-               break;
-       case 'c':
-               optc = 1;
-               break;
-       default:
-               return (-1);
-       }
-
-       if (opta && optc) {
-               (void) printf("warning: -a overrides -c\n");
-               optc = 0;
-       }
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(3 * lm_optB * lm_optT + 10);
-
-       return (0);
-}
-
-int
-benchmark_initbatch_once(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j;
-
-       int                     errors = 0;
-
-       ts->ts_lsns = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_lsns == NULL) {
-               errors ++;
-       }
-       ts->ts_accs = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_accs == NULL) {
-               errors ++;
-       }
-       ts->ts_cons = (int *)malloc(lm_optB * sizeof (int));
-       if (ts->ts_cons == NULL) {
-               errors ++;
-       }
-       ts->ts_adds =
-           (struct sockaddr_in *)malloc(lm_optB *
-           sizeof (struct sockaddr_in));
-       if (ts->ts_accs == NULL) {
-               errors ++;
-       }
-
-       j = FIRSTPORT;
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_lsns[i] = socket(AF_INET, SOCK_STREAM, 0);
-               if (ts->ts_lsns[i] == -1) {
-                       perror("socket");
-                       errors ++;
-               }
-
-               /*
-                * make accept socket non-blocking so in case of errors
-                * we don't hang
-                */
-
-               if (fcntl(ts->ts_lsns[i], F_SETFL, O_NDELAY) == -1) {
-                       perror("fcntl");
-                       errors ++;
-               }
-
-
-               if ((host = gethostbyname("localhost")) == NULL) {
-                       errors ++;
-               }
-
-               for (;;) {
-                       (void) memset(&ts->ts_adds[i], 0,
-                           sizeof (struct sockaddr_in));
-                       ts->ts_adds[i].sin_family = AF_INET;
-                       ts->ts_adds[i].sin_port = htons(j++);
-                       (void) memcpy(&ts->ts_adds[i].sin_addr.s_addr,
-                           host->h_addr_list[0], sizeof (struct in_addr));
-
-                       if (bind(ts->ts_lsns[i],
-                           (struct sockaddr *)&ts->ts_adds[i],
-                           sizeof (struct sockaddr_in)) == 0) {
-                               break;
-                       }
-
-                       if (errno != EADDRINUSE) {
-                               errors ++;
-                       }
-               }
-
-               if (listen(ts->ts_lsns[i], 5) == -1) {
-                       perror("listen");
-                       errors ++;
-               }
-       }
-       return (errors);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-       int                     result;
-
-       if (ts->ts_once++ == 0) {
-               if (errors += benchmark_initbatch_once(tsd) == -1) {
-                       return (-1);
-               }
-       }
-
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_cons[i] = socket(AF_INET, SOCK_STREAM, 0);
-               if (ts->ts_cons[i] == -1) {
-                       perror("init:socket");
-                       errors ++;
-               }
-
-               if (fcntl(ts->ts_cons[i], F_SETFL, O_NDELAY) == -1) {
-                       perror("init:fcntl");
-                       errors ++;
-               }
-
-               if (opta) {
-                       result = connect(ts->ts_cons[i],
-                           (struct sockaddr *)&ts->ts_adds[i],
-                           sizeof (struct sockaddr_in));
-                       if ((result == -1) && (errno != EINPROGRESS)) {
-                               perror("init:connect");
-                               errors ++;
-                       }
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-
-
-
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     result;
-       struct sockaddr_in      addr;
-       socklen_t               size;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (!opta) {
-               again:
-                       result = connect(ts->ts_cons[i],
-                           (struct sockaddr *)&ts->ts_adds[i],
-                           sizeof (struct sockaddr_in));
-                       if (result != 0 && errno != EISCONN) {
-                               if (errno == EINPROGRESS) {
-                                       struct pollfd pollfd;
-                                       if (optc)
-                                               continue;
-                                       pollfd.fd = ts->ts_cons[i];
-                                       pollfd.events = POLLOUT;
-                                       if (poll(&pollfd, 1, -1) == 1)
-                                               goto again;
-                               }
-
-                               res->re_errors ++;
-                               perror("benchmark:connect");
-                               continue;
-                       }
-               }
-
-               if (!optc) {
-                       size = sizeof (struct sockaddr);
-                       for (;;) {
-                               struct pollfd pollfd;
-                               result = accept(ts->ts_lsns[i],
-                                   (struct sockaddr *)&addr, &size);
-                               if (result > 0 || (result == -1 &&
-                                   errno != EAGAIN))
-                                       break;
-                               pollfd.fd = ts->ts_lsns[i];
-                               pollfd.events = POLLIN;
-                               if (poll(&pollfd, 1, -1) != 1)
-                                       break;
-                       }
-
-                       ts->ts_accs[i] = result;
-                       if (result == -1) {
-                               res->re_errors ++;
-                               perror("benchmark:accept");
-                               continue;
-                       }
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-
-               if (!optc) {
-                       (void) close(ts->ts_accs[i]);
-               }
-               (void) close(ts->ts_cons[i]);
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/coreos_bench.sh b/tools/tests/libMicro/coreos_bench.sh
deleted file mode 100755 (executable)
index a892050..0000000
+++ /dev/null
@@ -1,829 +0,0 @@
-#!/bin/sh
-#
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-# usage function - defines all the options that can be given to this script.
-function usage {
-       echo "Usage"
-       echo "$0 [-l] [-h] [name of test]"
-       echo "-l               : This option runs the lmbench tests along with the default libmicro tests."
-       echo "-h               : Help. This option displays information on how to run the script. "
-       echo "[name of test]   : This option runs only the test that is specified"
-       echo ""
-       echo "Examples"
-       echo "$0               : This is the defualt execution. This will run only the default libmicro tests."
-       echo "$0 -l            : This will run the lmbench tests too "
-       echo "$0 getppid       : This will run only the getppid tests"
-       exit
-       
-}
-
-if [ $# -eq 1 ]
-then
-       lmbench=2   # to check if only a single test is to be run. e.g, ./coreos_bench.sh getppid
-else
-       lmbench=0   # to run the default libMicro tests, without the lmbench tests.
-fi
-
-while getopts "lh" OPT_LIST
-do
-       case $OPT_LIST in 
-               l) lmbench=1;;   # to run the libmicro tests including the lmbench tests.
-               h) usage;;
-               *) usage;;
-       esac
-done
-
-
-tattle="./tattle"
-
-bench_version=0.4.0
-libmicro_version=`$tattle -V`
-
-case $libmicro_version in
-$bench_version)
-       ;;
-*)
-       echo "ERROR: libMicro version doesn't match 'coreos_bench' script version"
-       exit 1
-esac
-
-TMPROOT=/private/tmp/libmicro.$$
-VARROOT=/private/var/tmp/libmicro.$$
-mkdir -p $TMPROOT
-mkdir -p $VARROOT
-
-#if 1 /* Apple modified code */
-
-# If the testsuite finish completely or if it is interrupted before 
-# completion, re-enable stepper for normal operation of the machine
-# see rdar://6243819 for details
-trap "rm -rf $TMPROOT $VARROOT && sudo pstates -e && exit" 0 2
-
-#else
-trap "rm -rf $TMPROOT $VARROOT && exit" 0 2
-#endif /* End of Apple modified code
-
-TFILE=$TMPROOT/data
-IFILE=$TMPROOT/ifile
-TDIR1=$TMPROOT/0/1/2/3/4/5/6/7/8/9
-TDIR2=$TMPROOT/1/2/3/4/5/6/7/8/9/0
-VFILE=$VARROOT/data
-VDIR1=$VARROOT/0/1/2/3/4/5/6/7/8/9
-VDIR2=$VARROOT/1/2/3/4/5/6/7/8/9/0
-
-
-OPTS="-E -C 200 -L -S -W"
-
-dd if=/dev/zero of=$TFILE bs=1024k count=10 2>/dev/null
-dd if=/dev/zero of=$VFILE bs=1024k count=10 2>/dev/null
-mkdir -p $TDIR1 $TDIR2
-mkdir -p $VDIR1 $VDIR2
-
-touch $IFILE
-/usr/bin/touch /private/var/tmp/lmbench
-
-
-# produce benchmark header for easier comparisons
-
-hostname=`uname -n`
-
-if [ -f /usr/sbin/psrinfo ]; then
-       p_count=`psrinfo|wc -l`
-       p_mhz=`psrinfo -v | awk '/operates/{print $6 "MHz"; exit }'`
-       p_type=`psrinfo -vp 2>/dev/null | awk '{if (NR == 3) {print $0; exit}}'` 
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-fi
-
-if [ -f /proc/cpuinfo ]; then
-       p_count=`egrep processor /proc/cpuinfo | wc -l`
-       p_mhz=`awk -F: '/cpu MHz/{printf("%5.0f00Mhz\n",$2/100); exit}' /proc/cpuinfo`
-       p_type=`awk -F: '/model name/{print $2; exit}' /proc/cpuinfo`
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-else
-## Mac OS X specific stuff
-# first, get ugly output, in case pretty output isn't available
-#
-       p_count=`sysctl -n hw.physicalcpu`
-       p_mhz=`sysctl -n hw.cpufrequency`
-       p_type=`sysctl -n hw.model`
-
-if [ -x /usr/sbin/system_profiler ]; then
-       # <rdar://4655981> requires this hunk of work-around
-       # grep the XML for the characteristic we need. The key appears twice, so grep for the useful key (with 'string')
-       # use sed to strip off the <string></string> and the tabs in front of the string.  So much work for so little result.
-       #
-               p_mhz=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 current_processor_speed | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-               p_type=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 cpu_type | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-fi
-
-# look for en0 (usually ethernet) if that isn't there try en1 (usually wireless) else give up
-       p_ipaddr=`ipconfig getpacket en0 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       if [ ! $p_ipaddr  ]; then
-               p_ipaddr=`ipconfig getpacket en1 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       elif [ ! $p_ipaddr ]; then
-               p_ipaddr="unknown"
-       fi
-fi
-
-printf "\n\n!Libmicro_#:   %30s\n" $libmicro_version
-printf "!Options:      %30s\n" "$OPTS"
-printf "!Machine_name: %30s\n" "$hostname"
-printf "!OS_name:      %30s\n" `uname -s`
-printf "!OS_release:   %30s\n" `sw_vers -productVersion`
-printf "!OS_build:     %30.18s\n" "`sw_vers -buildVersion`"
-printf "!Processor:    %30s\n" `arch`
-printf "!#CPUs:        %30s\n" $p_count
-printf "!CPU_MHz:      %30s\n" "$p_mhz"
-printf "!CPU_NAME:     %30s\n" "$p_type"
-printf "!IP_address:   %30s\n" "$p_ipaddr"
-printf "!Run_by:       %30s\n" $LOGNAME
-printf "!Date:        %30s\n" "`date '+%D %R'`"
-printf "!Compiler:     %30s\n" `$tattle -c`
-printf "!Compiler Ver.:%30s\n" "`$tattle -v`"
-printf "!sizeof(long): %30s\n" `$tattle -s`
-printf "!extra_CFLAGS: %30s\n" "`$tattle -f`"
-printf "!TimerRes:     %30s\n\n\n" "`$tattle -r`"
-bin_dir="$TMPROOT/bin"
-
-mkdir -p $bin_dir
-cp bin-*/exec_bin $bin_dir/$A
-
-cp ./apple/bin-*/posix_spawn_bin $bin_dir/$A
-
-newline=0
-
-#if 1 /* Apple added code */
-
-# We need to disable the stepper to prevent it from causing
-# wide variations in results; see rdar://6243819 for details
-
-pstates=/usr/local/bin/pstates
-if [ -x $pstates ]; then
-        echo "Disabling stepper to provide more consistent results of benchmark run"
-        sudo $pstates -d; sudo pstates -p 0
-else
-        echo "ERROR: No $pstates found; To disable stepper we need $pstates" 1>&2
-        echo "Install AppleInternal package which provides $pstates and execute 'coreos_bench' again" 1>&2
-        echo 1>&2
-        echo "Note: If you cannot install AppleInternal package which provides $pstates, then use 'bench' script to run libMicro testsuite" 1>&2       
-       exit 1
-fi
-
-#endif /* End of Apple code */
-
-#
-# Everything below the while loop is input for the while loop if
-# you have any tests which can't run in the while loop, put
-# them above this comment
-#
-while read A B
-do
-       # $A contains the command, $B contains the arguments
-       # we echo blank lines and comments
-       # we skip anything which fails to match *$1* (useful if
-       # we only want to test one case, but a nasty hack)
-
-       case $A in
-       \#*)
-               echo "$A $B"
-               newline=1
-               continue
-               ;;
-       
-       "")
-               if [ $newline -eq 1 ]
-               then
-                       newline=0
-                       echo
-                       echo
-               fi
-
-               continue
-               ;;
-
-       *$1*)
-               # Default execution without the lmbench tests. 
-               # checks if there is no argument passed by the user.
-               if [  $lmbench -eq 0 ]
-               then
-                       string=lmbench
-                       if [ "${A:0:7}" == "$string" ]
-                       then
-                               continue
-                       fi
-               fi
-                       
-               ;;
-       
-       *)              
-               if [ $lmbench -ne 1 ]
-               then
-                       continue
-               fi
-               ;;
-       esac
-
-       if [ ! -f $bin_dir/$A ]
-       then
-               cp bin-*/$A $bin_dir/$A
-       fi
-
-       echo
-
-       (cd $TMPROOT && eval "bin/$A $B")
-
-       echo
-       echo
-done <<.
-
-#
-# Obligatory null system call: use very short time
-# for default since SuSe implements this "syscall" in userland
-#
-
-getpid         $OPTS -N "getpid" -I 5
-getppid                $OPTS -N "getppid" -I 5
-
-getenv         $OPTS -N "getenv"       -s 100 -I 100    
-getenv         $OPTS -N "getenvT2"     -s 100 -I 100   -T 2 
-
-gettimeofday   $OPTS -N "gettimeofday"          
-
-log            $OPTS -N "log"  -I 20   -B 300000        
-exp            $OPTS -N "exp"  -I 20   -B 100000        
-lrand48                $OPTS -N "lrand48"
-
-memset         $OPTS -N "memset_10"    -s 10   -I 10 
-memset         $OPTS -N "memset_256"   -s 256  -I 20
-memset         $OPTS -N "memset_256_u" -s 256   -a 1 -I 20 
-memset         $OPTS -N "memset_1k"    -s 1k    -I 100 -B 2000
-memset         $OPTS -N "memset_4k"    -s 4k    -I 250 -B 500
-memset         $OPTS -N "memset_4k_uc" -s 4k    -u -I 400
-
-memset         $OPTS -N "memset_10k"   -s 10k  -I 600 -B 500
-memset         $OPTS -N "memset_1m"    -s 1m   -I 200000
-memset         $OPTS -N "memset_10m"   -s 10m -I 2000000 
-memset         $OPTS -N "memsetP2_10m" -s 10m -P 2 -I 2000000 
-
-memrand                $OPTS -N "memrand"      -s 40m -B 10000
-
-# This is an elided test and is not ported yet.
-# Check Makefile.darwin for list of elided tests  
-# cachetocache $OPTS -N "cachetocache" -s 100k -T 2 -I 200
-
-isatty         $OPTS -N "isatty_yes"   
-isatty         $OPTS -N "isatty_no"  -f $IFILE
-
-malloc         $OPTS -N "malloc_10"    -s 10    -g 10 -I 50
-malloc         $OPTS -N "malloc_100"   -s 100   -g 10 -I 50
-malloc         $OPTS -N "malloc_1k"    -s 1k    -g 10 -I 50
-malloc         $OPTS -N "malloc_10k"   -s 10k   -g 10 -I 50
-malloc         $OPTS -N "malloc_100k"  -s 100k  -g 10 -I 2000
-
-malloc         $OPTS -N "mallocT2_10"    -s 10   -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_100"   -s 100  -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_1k"    -s 1k   -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_10k"   -s 10k  -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_100k"  -s 100k -g 10 -T 2 -I 10000
-
-close          $OPTS -N "close_bad"            -B 96           -b
-close          $OPTS -N "close_tmp"            -B 64           -f $TFILE
-close          $OPTS -N "close_usr"            -B 64           -f $VFILE
-close          $OPTS -N "close_zero"           -B 64           -f /dev/zero
-close_tcp      $OPTS -N "close_tcp"            -B 32  
-
-memcpy         $OPTS -N "memcpy_10"    -s 10   -I 10 
-memcpy         $OPTS -N "memcpy_1k"    -s 1k   -I 50
-memcpy         $OPTS -N "memcpy_10k"   -s 10k  -I 800
-memcpy         $OPTS -N "memcpy_1m"    -s 1m   -I 500000
-memcpy         $OPTS -N "memcpy_10m"   -s 10m  -I 5000000
-
-strcpy         $OPTS -N "strcpy_10"    -s 10   -I 5 
-strcpy         $OPTS -N "strcpy_1k"    -s 1k   -I 100
-
-strlen         $OPTS -N "strlen_10"    -s 10   -I 5
-strlen         $OPTS -N "strlen_1k"    -s 1k   -I 100
-
-strchr         $OPTS -N "strchr_10"    -s 10   -I 5
-strchr         $OPTS -N "strchr_1k"    -s 1k   -I 200
-strcmp         $OPTS -N "strcmp_10"    -s 10   -I 10
-strcmp         $OPTS -N "strcmp_1k"    -s 1k   -I 200
-
-strcasecmp     $OPTS -N "scasecmp_10"  -s 10 -I 50 -B 2000
-strcasecmp     $OPTS -N "scasecmp_1k"  -s 1k -I 20000 -B 100
-
-strtol         $OPTS -N "strtol"      -I 20      
-
-# This is an elided test and is not ported yet.     
-# Check Makefile.darwin for list of elided tests
-# getcontext   $OPTS -N "getcontext"  -I 100
-
-# This is an elided test and is not ported yet.     
-# Check Makefile.darwin for list of elided tests
-# setcontext   $OPTS -N "setcontext"  -I 100
-
-mutex          $OPTS -N "mutex_st"     -I 10
-mutex          $OPTS -N "mutex_mt"     -t -I 10        
-mutex          $OPTS -N "mutex_T2"     -T 2  -I 100
-
-longjmp                $OPTS -N "longjmp"      -I 10
-siglongjmp     $OPTS -N "siglongjmp"   -I 20
-
-getrusage      $OPTS -N "getrusage"    -I 200
-
-times          $OPTS -N "times"        -I 200
-time           $OPTS -N "time"         -I 50
-localtime_r    $OPTS -N "localtime_r"  -I 200  
-strftime       $OPTS -N "strftime" -I 10000 -B 100 
-
-mktime         $OPTS -N "mktime"       -I 500   
-mktime         $OPTS -N "mktimeT2" -T 2 -I 1000 
-
-cascade_mutex  $OPTS -N "c_mutex_1"    -I 50
-cascade_mutex  $OPTS -N "c_mutex_10"   -T 10 -I 5000
-cascade_mutex  $OPTS -N "c_mutex_200"  -T 200  -I 2000000
-
-cascade_cond   $OPTS -N "c_cond_1"     -I 100
-cascade_cond   $OPTS -N "c_cond_10"    -T 10   -I 3000
-cascade_cond   $OPTS -N "c_cond_200"   -T 200  -I 2000000
-
-cascade_lockf  $OPTS -N "c_lockf_1"    -I 1000 
-cascade_lockf  $OPTS -N "c_lockf_10"   -P 10 -I 50000
-cascade_lockf  $OPTS -N "c_lockf_200"  -P 200 -I 5000000
-
-cascade_flock  $OPTS -N "c_flock"      -I 1000 
-cascade_flock  $OPTS -N "c_flock_10"   -P 10   -I 50000
-cascade_flock  $OPTS -N "c_flock_200"  -P 200  -I 5000000
-
-cascade_fcntl  $OPTS -N "c_fcntl_1"    -I 2000         
-cascade_fcntl  $OPTS -N "c_fcntl_10"   -P 10 -I 20000
-cascade_fcntl  $OPTS -N "c_fcntl_200"  -P 200  -I 5000000
-
-file_lock      $OPTS -N "file_lock"   -I 1000         
-
-getsockname    $OPTS -N "getsockname"  -I 100
-getpeername    $OPTS -N "getpeername"  -I 100
-
-chdir          $OPTS -N "chdir_tmp"    -I 2000         $TDIR1 $TDIR2
-chdir          $OPTS -N "chdir_usr"    -I 2000         $VDIR1 $VDIR2
-
-chdir          $OPTS -N "chgetwd_tmp"  -I 3000 -g $TDIR1 $TDIR2
-chdir          $OPTS -N "chgetwd_usr"  -I 3000 -g $VDIR1 $VDIR2
-
-realpath       $OPTS -N "realpath_tmp" -I 3000         -f $TDIR1
-realpath       $OPTS -N "realpath_usr" -I 3000 -f $VDIR1
-
-stat           $OPTS -N "stat_tmp" -I 1000             -f $TFILE
-stat           $OPTS -N "stat_usr" -I 1000             -f $VFILE
-
-lmbench_stat           $OPTS -N "lmbench_stat_tmp" -I 1000             -f $TFILE
-lmbench_stat           $OPTS -N "lmbench_stat_usr" -I 10000 -B 100             -f /private/var/tmp/lmbench
-
-#
-# lmbench uses a touched empty file in /private/var/tmp
-# libMicro uses a 1M file in a directory off /private/var/tmp
-# performance difference is ~ 0.2 usecs/call
-#
-# why? - walking the dir tree, empty file vs. non-empty file, non-empty dir
-# in the case of libMicro, etc., etc.
-#
-
-lmbench_stat           $OPTS -N "lmbench_stat_usr - Default" -I 10000 -B 100   -f /private/var/tmp/lmbench
-
-lmbench_fstat          $OPTS -N "lmbench_fstat_tmp" -I 1000            -f $TFILE
-lmbench_fstat          $OPTS -N "lmbench_fstat_usr" -I 10000 -B 100            -f /private/var/tmp/lmbench
-
-# see stat test to understand why we are using /private/var/tmp/lmbench
-
-lmbench_fstat          $OPTS -N "lmbench_fstat_usr - Default" -I 10000 -B 100  -f /private/var/tmp/lmbench
-
-lmbench_openclose      $OPTS -N "lmbench_openclose - Default" -I 10000 -B 100  -f /private/var/tmp/lmbench
-
-lmbench_select_file $OPTS -N "lmbench_select_file_10"  -n 10  -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_100" -n 100 -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_250" -n 250 -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_500" -n 500 -B 100
-
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_10"  -n 10  -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_100" -n 100 -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_250" -n 250 -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_500" -n 500 -B 100
-
-fcntl          $OPTS -N "fcntl_tmp"    -I 100  -f $TFILE
-fcntl          $OPTS -N "fcntl_usr"    -I 100  -f $VFILE
-fcntl_ndelay   $OPTS -N "fcntl_ndelay" -I 100  
-
-lseek          $OPTS -N "lseek_t8k"    -s 8k   -I 50   -f $TFILE
-lseek          $OPTS -N "lseek_u8k"    -s 8k   -I 50   -f $VFILE
-
-open           $OPTS -N "open_tmp"             -B 256          -f $TFILE
-open           $OPTS -N "open_usr"             -B 256          -f $VFILE
-open           $OPTS -N "open_zero"            -B 256          -f /dev/zero
-
-dup            $OPTS -N "dup"                  -B 512   
-
-socket         $OPTS -N "socket_u"             -B 256
-socket         $OPTS -N "socket_i"             -B 256          -f PF_INET
-
-socketpair     $OPTS -N "socketpair"           -B 256
-
-setsockopt     $OPTS -N "setsockopt"           -I 200
-
-bind           $OPTS -N "bind"                 -B 100
-
-listen         $OPTS -N "listen"               -B 100
-
-#connection    $OPTS -N "connection"           -B 256 
-
-poll           $OPTS -N "poll_10"      -n 10   -I 500
-poll           $OPTS -N "poll_100"     -n 100  -I 1000
-poll           $OPTS -N "poll_1000"    -n 1000 -I 5000
-
-poll           $OPTS -N "poll_w10"     -n 10   -I 500          -w 1
-poll           $OPTS -N "poll_w100"    -n 100  -I 2000         -w 10
-poll           $OPTS -N "poll_w1000"   -n 1000 -I 40000        -w 100
-
-select         $OPTS -N "select_10"    -n 10   -I 500
-select         $OPTS -N "select_100"   -n 100  -I 1000
-select         $OPTS -N "select_1000"  -n 1000 -I 5000
-
-select         $OPTS -N "select_w10"   -n 10   -I 500          -w 1
-select         $OPTS -N "select_w100"  -n 100  -I 2000         -w 10
-select         $OPTS -N "select_w1000" -n 1000 -I 40000        -w 100
-
-semop          $OPTS -N "semop" -I 200
-
-sigaction      $OPTS -N "sigaction" -I 100
-signal         $OPTS -N "signal" -I 1000
-sigprocmask    $OPTS -N "sigprocmask" -I 200
-
-lmbench_lat_sig_install        $OPTS -N "lmbench_siginstall"
-# sigcatch and sigsend need to be evaluated together
-# lmbench framework will allow multiple measurements within the same
-# benchmark test which allow them to factor out the cost of sending
-# a signal from catching one
-#
-# for our purposes sigcatch results - sigsend results yield
-# lmbench sig handler overhead measurements
-lmbench_lat_sig_catch  $OPTS -N "lmbench_sigcatch" 
-lmbench_lat_sig_send   $OPTS -N "lmbench_sigsend" 
-
-
-pthread_create  $OPTS -N "pthread_8"           -B 8
-pthread_create  $OPTS -N "pthread_32"          -B 32
-pthread_create  $OPTS -N "pthread_128"         -B 128
-pthread_create  $OPTS -N "pthread_512"         -B 512
-
-fork           $OPTS -N "fork_10"              -B 10
-fork           $OPTS -N "fork_100"             -B 100  -C 100
-
-#fork          $OPTS -N "fork_1000"            -B 1000 -C 50
-
-exit           $OPTS -N "exit_10"              -B 10
-exit           $OPTS -N "exit_100"             -B 100
-
-#exit          $OPTS -N "exit_1000"            -B 1000 -C 50
-
-exit           $OPTS -N "exit_10_nolibc"       -e -B 10
-
-exec           $OPTS -N "exec" -B 10
-
-posix_spawn    $OPTS -N "posix_spawn" -B 10
-
-system         $OPTS -N "system" -I 1000000
-
-recurse                $OPTS -N "recurse"              -B 512
-
-read           $OPTS -N "read_t1k"     -s 1k -B 50                     -f $TFILE
-read           $OPTS -N "read_t10k"    -s 10k  -B 16           -f $TFILE
-read           $OPTS -N "read_t100k"   -s 100k -B 4            -f $TFILE
-
-read           $OPTS -N "read_u1k"     -s 1k   -B 50           -f $VFILE
-read           $OPTS -N "read_u10k"    -s 10k  -B 16           -f $VFILE
-read           $OPTS -N "read_u100k"   -s 100k -B 4            -f $VFILE
-
-read           $OPTS -N "read_z1k"     -s 1k   -B 100          -f /dev/zero 
-read           $OPTS -N "read_z10k"    -s 10k  -B 30           -f /dev/zero 
-read           $OPTS -N "read_z100k"   -s 100k -B 4            -f /dev/zero 
-read           $OPTS -N "read_zw100k"  -s 100k -B 4         -w -f /dev/zero 
-
-lmbench_read           $OPTS -N "read_t1b"     -s 1 -B 50                      -f $TFILE
-lmbench_read           $OPTS -N "read_t1k"     -s 1k -B 50                     -f $TFILE
-lmbench_read           $OPTS -N "read_t10k"    -s 10k  -B 16           -f $TFILE
-lmbench_read           $OPTS -N "read_t100k"   -s 100k -B 4            -f $TFILE
-
-lmbench_read           $OPTS -N "read_u1b"     -s 1    -B 50           -f $VFILE
-lmbench_read           $OPTS -N "read_u1k"     -s 1k   -B 50           -f $VFILE
-lmbench_read           $OPTS -N "read_u10k"    -s 10k  -B 16           -f $VFILE
-lmbench_read           $OPTS -N "read_u100k"   -s 100k -B 4            -f $VFILE
-
-lmbench_read           $OPTS -N "read_z1b - Default"   -s 1    -B 100          -f /dev/zero 
-lmbench_read           $OPTS -N "read_z1k"     -s 1k   -B 100          -f /dev/zero 
-lmbench_read           $OPTS -N "read_z10k"    -s 10k  -B 30           -f /dev/zero 
-lmbench_read           $OPTS -N "read_z100k"   -s 100k -B 4            -f /dev/zero 
-lmbench_read           $OPTS -N "read_zw100k"  -s 100k -B 4         -w -f /dev/zero 
-
-write          $OPTS -N "write_t1k"    -s 1k   -B 50           -f $TFILE
-write          $OPTS -N "write_t10k"   -s 10k  -B 25           -f $TFILE
-write          $OPTS -N "write_t100k"  -s 100k -B 4            -f $TFILE
-
-write          $OPTS -N "write_u1k"    -s 1k   -B 50           -f $VFILE
-write          $OPTS -N "write_u10k"   -s 10k  -B 25           -f $VFILE
-write          $OPTS -N "write_u100k"  -s 100k -B 4            -f $VFILE
-
-write          $OPTS -N "write_n1k"    -s 1k   -I 100 -B 0     -f /dev/null 
-write          $OPTS -N "write_n10k"   -s 10k  -I 100 -B 0     -f /dev/null 
-write          $OPTS -N "write_n100k"  -s 100k -I 100 -B 0     -f /dev/null 
-
-lmbench_write          $OPTS -N "lmbench_write_t1b"    -s 1    -B 50           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t1k"    -s 1k   -B 50           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t10k"   -s 10k  -B 25           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t100k"  -s 100k -B 4            -f $TFILE
-
-lmbench_write          $OPTS -N "lmbench_write_u1b"    -s 1    -B 50           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u1k"    -s 1k   -B 50           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u10k"   -s 10k  -B 25           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u100k"  -s 100k -B 4            -f $VFILE
-
-lmbench_write          $OPTS -N "lmbench_write_n1b - Default"  -s 1    -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n1k"    -s 1k   -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n10k"   -s 10k  -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n100k"  -s 100k -I 100 -B 0     -f /dev/null 
-
-writev         $OPTS -N "writev_t1k"   -s 1k   -B 20           -f $TFILE
-writev         $OPTS -N "writev_t10k"  -s 10k  -B 4            -f $TFILE
-writev         $OPTS -N "writev_t100k" -s 100k                 -f $TFILE
-
-writev         $OPTS -N "writev_u1k"   -s 1k   -B 20           -f $VFILE
-writev         $OPTS -N "writev_u10k"  -s 10k  -B 4            -f $VFILE
-writev         $OPTS -N "writev_u100k" -s 100k                 -f $VFILE
-
-writev         $OPTS -N "writev_n1k"   -s 1k   -I 100 -B 0     -f /dev/null 
-writev         $OPTS -N "writev_n10k"  -s 10k  -I 100 -B 0     -f /dev/null 
-writev         $OPTS -N "writev_n100k" -s 100k -I 100 -B 0     -f /dev/null 
-
-pread          $OPTS -N "pread_t1k"    -s 1k   -I 300          -f $TFILE
-pread          $OPTS -N "pread_t10k"   -s 10k  -I 1000         -f $TFILE
-pread          $OPTS -N "pread_t100k"  -s 100k -I 10000        -f $TFILE
-
-pread          $OPTS -N "pread_u1k"    -s 1k   -I 300          -f $VFILE
-pread          $OPTS -N "pread_u10k"   -s 10k  -I 1000         -f $VFILE
-pread          $OPTS -N "pread_u100k"  -s 100k -I 10000        -f $VFILE
-
-pread          $OPTS -N "pread_z1k"    -s 1k   -I 300          -f /dev/zero 
-pread          $OPTS -N "pread_z10k"   -s 10k  -I 1000         -f /dev/zero 
-pread          $OPTS -N "pread_z100k"  -s 100k -I 2000 -f /dev/zero 
-pread          $OPTS -N "pread_zw100k" -s 100k -w -I 10000     -f /dev/zero 
-
-pwrite         $OPTS -N "pwrite_t1k"   -s 1k   -I 500          -f $TFILE
-pwrite         $OPTS -N "pwrite_t10k"  -s 10k  -I 1000         -f $TFILE
-pwrite         $OPTS -N "pwrite_t100k" -s 100k -I 10000        -f $TFILE
-
-pwrite         $OPTS -N "pwrite_u1k"   -s 1k   -I 500          -f $VFILE
-pwrite         $OPTS -N "pwrite_u10k"  -s 10k  -I 1000         -f $VFILE
-pwrite         $OPTS -N "pwrite_u100k" -s 100k -I 20000        -f $VFILE
-
-pwrite         $OPTS -N "pwrite_n1k"   -s 1k   -I 100          -f /dev/null 
-pwrite         $OPTS -N "pwrite_n10k"  -s 10k  -I 100          -f /dev/null 
-pwrite         $OPTS -N "pwrite_n100k" -s 100k -I 100          -f /dev/null 
-
-mmap           $OPTS -N "mmap_t8k"     -l 8k   -I 1000         -f $TFILE
-mmap           $OPTS -N "mmap_t128k"   -l 128k -I 1000         -f $TFILE
-mmap           $OPTS -N "mmap_u8k"     -l 8k   -I 1000         -f $VFILE
-mmap           $OPTS -N "mmap_u128k"   -l 128k -I 1000         -f $VFILE
-mmap           $OPTS -N "mmap_a8k"     -l 8k   -I 200          -f MAP_ANON
-mmap           $OPTS -N "mmap_a128k"   -l 128k -I 200          -f MAP_ANON
-
-
-
-mmap           $OPTS -N "mmap_rt8k"    -l 8k   -I 2000 -r      -f $TFILE
-mmap           $OPTS -N "mmap_rt128k"  -l 128k -I 20000 -r     -f $TFILE
-mmap           $OPTS -N "mmap_ru8k"    -l 8k   -I 2000 -r      -f $VFILE
-mmap           $OPTS -N "mmap_ru128k"  -l 128k -I 20000 -r     -f $VFILE
-mmap           $OPTS -N "mmap_ra8k"    -l 8k   -I 2000 -r      -f MAP_ANON
-mmap           $OPTS -N "mmap_ra128k"  -l 128k -I 20000 -r     -f MAP_ANON
-
-
-mmap           $OPTS -N "mmap_wt8k"    -l 8k   -I 5000 -w      -f $TFILE
-mmap           $OPTS -N "mmap_wt128k"  -l 128k -I 50000 -w     -f $TFILE
-mmap           $OPTS -N "mmap_wu8k"    -l 8k   -I 5000 -w      -f $VFILE
-mmap           $OPTS -N "mmap_wu128k"  -l 128k -I 500000 -w    -f $VFILE
-mmap           $OPTS -N "mmap_wa8k"    -l 8k   -I 3000 -w      -f MAP_ANON
-mmap           $OPTS -N "mmap_wa128k"  -l 128k -I 50000 -w     -f MAP_ANON
-
-
-munmap         $OPTS -N "unmap_t8k"    -l 8k   -I 500          -f $TFILE
-munmap         $OPTS -N "unmap_t128k"  -l 128k -I 500          -f $TFILE
-munmap         $OPTS -N "unmap_u8k"    -l 8k   -I 500          -f $VFILE
-munmap         $OPTS -N "unmap_u128k"  -l 128k -I 500          -f $VFILE
-munmap         $OPTS -N "unmap_a8k"    -l 8k   -I 500          -f MAP_ANON
-munmap         $OPTS -N "unmap_a128k"  -l 128k -I 500          -f MAP_ANON
-
-
-munmap         $OPTS -N "unmap_rt8k"   -l 8k   -I 1000 -r      -f $TFILE
-munmap         $OPTS -N "unmap_rt128k" -l 128k -I 3000 -r      -f $TFILE
-munmap         $OPTS -N "unmap_ru8k"   -l 8k   -I 1000 -r      -f $VFILE
-munmap         $OPTS -N "unmap_ru128k" -l 128k -I 3000 -r      -f $VFILE
-munmap         $OPTS -N "unmap_ra8k"   -l 8k   -I 1000 -r      -f MAP_ANON
-munmap         $OPTS -N "unmap_ra128k" -l 128k -I 2000 -r      -f MAP_ANON
-
-connection     $OPTS -N "conn_connect"         -B 256  -c
-
-
-munmap         $OPTS -N "unmap_wt8k"   -l 8k   -I 1000 -w      -f $TFILE
-munmap         $OPTS -N "unmap_wt128k" -l 128k -I 10000        -w      -f $TFILE
-munmap         $OPTS -N "unmap_wu8k"   -l 8k   -I 1000 -w      -f $VFILE
-munmap         $OPTS -N "unmap_wu128k" -l 128k -I 50000        -w -B 10        -f $VFILE
-munmap         $OPTS -N "unmap_wa8k"   -l 8k   -I 1000 -w      -f MAP_ANON
-munmap         $OPTS -N "unmap_wa128k" -l 128k -I 10000        -w      -f MAP_ANON
-
-mprotect       $OPTS -N "mprot_z8k"    -l 8k  -I 300                   -f /dev/zero
-mprotect       $OPTS -N "mprot_z128k"  -l 128k -I 500          -f /dev/zero
-mprotect       $OPTS -N "mprot_wz8k"   -l 8k   -I 500  -w      -f /dev/zero
-mprotect       $OPTS -N "mprot_wz128k" -l 128k -I 1000 -w      -f /dev/zero
-mprotect       $OPTS -N "mprot_twz8k"  -l 8k   -I 1000 -w -t   -f /dev/zero
-mprotect       $OPTS -N "mprot_tw128k" -l 128k -I 2000 -w -t   -f /dev/zero
-mprotect       $OPTS -N "mprot_tw4m"   -l 4m   -w -t -B 1  -f /dev/zero
-
-pipe           $OPTS -N "pipe_pst1"    -s 1    -I 1000 -x pipe -m st
-pipe           $OPTS -N "pipe_pmt1"    -s 1    -I 8000 -x pipe -m mt
-pipe           $OPTS -N "pipe_pmp1"    -s 1    -I 8000 -x pipe -m mp
-pipe           $OPTS -N "pipe_pst4k"   -s 4k   -I 1000 -x pipe -m st
-pipe           $OPTS -N "pipe_pmt4k"   -s 4k   -I 8000 -x pipe -m mt
-pipe           $OPTS -N "pipe_pmp4k"   -s 4k   -I 8000 -x pipe -m mp
-
-pipe           $OPTS -N "pipe_sst1"    -s 1    -I 1000 -x sock -m st
-pipe           $OPTS -N "pipe_smt1"    -s 1    -I 8000 -x sock -m mt
-pipe           $OPTS -N "pipe_smp1"    -s 1    -I 8000 -x sock -m mp
-pipe           $OPTS -N "pipe_sst4k"   -s 4k   -I 1000 -x sock -m st
-pipe           $OPTS -N "pipe_smt4k"   -s 4k   -I 8000 -x sock -m mt
-pipe           $OPTS -N "pipe_smp4k"   -s 4k   -I 8000 -x sock -m mp
-
-pipe           $OPTS -N "pipe_tst1"    -s 1    -I 1000 -x tcp  -m st
-pipe           $OPTS -N "pipe_tmt1"    -s 1    -I 8000 -x tcp  -m mt
-pipe           $OPTS -N "pipe_tmp1"    -s 1    -I 8000 -x tcp  -m mp
-pipe           $OPTS -N "pipe_tst4k"   -s 4k   -I 1000 -x tcp  -m st
-pipe           $OPTS -N "pipe_tmt4k"   -s 4k   -I 8000 -x tcp  -m mt
-pipe           $OPTS -N "pipe_tmp4k"   -s 4k   -I 8000 -x tcp  -m mp
-
-#connection    $OPTS -N "conn_accept"          -B 256      -a
-
-lmbench_bw_unix -B 11 -L -W
-
-lmbench_bw_mem $OPTS -N lmbench_bcopy_512 -s 512 -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_1k -s 1k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_2k -s 2k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_4k -s 4k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_8k -s 8k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_16k -s 16k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_32k -s 32k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_64k -s 64k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_128k -s 128k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_256k -s 256k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_512k -s 512k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_1m -s 1m -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bzero_512 -s 512 -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_1k -s 1k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_2k -s 2k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_4k -s 4k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_8k -s 8k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_16k -s 16k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_32k -s 32k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_64k -s 64k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_128k -s 128k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_256k -s 256k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_512k -s 512k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_1m -s 1m -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_512 -s 512 -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_1k -s 1k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_2k -s 2k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_4k -s 4k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_8k -s 8k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_16k -s 16k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_32k -s 32k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_64k -s 64k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_128k -s 128k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_256k -s 256k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_512k -s 512k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_1m -s 1m -x fcp
-lmbench_bw_mem $OPTS -N lmbench_cp_512 -s 512 -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_1k -s 1k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_2k -s 2k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_4k -s 4k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_8k -s 8k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_16k -s 16k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_32k -s 32k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_64k -s 64k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_128k -s 128k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_256k -s 256k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_512k -s 512k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_1m -s 1m -x cp
-lmbench_bw_mem $OPTS -N lmbench_frd_512 -s 512 -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_1k -s 1k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_2k -s 2k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_4k -s 4k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_8k -s 8k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_16k -s 16k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_32k -s 32k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_64k -s 64k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_128k -s 128k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_256k -s 256k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_512k -s 512k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_1m -s 1m -x frd
-lmbench_bw_mem $OPTS -N lmbench_rd_512 -s 512 -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_1k -s 1k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_2k -s 2k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_4k -s 4k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_8k -s 8k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_16k -s 16k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_32k -s 32k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_64k -s 64k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_128k -s 128k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_256k -s 256k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_512k -s 512k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_1m -s 1m -x rd
-lmbench_bw_mem $OPTS -N lmbench_fwr_512 -s 512 -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_1k -s 1k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_2k -s 2k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_4k -s 4k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_8k -s 8k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_16k -s 16k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_32k -s 32k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_64k -s 64k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_128k -s 128k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_256k -s 256k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_512k -s 512k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_1m -s 1m -x fwr
-lmbench_bw_mem $OPTS -N lmbench_wr_512 -s 512 -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_1k -s 1k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_2k -s 2k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_4k -s 4k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_8k -s 8k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_16k -s 16k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_32k -s 32k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_64k -s 64k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_128k -s 128k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_256k -s 256k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_512k -s 512k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_1m -s 1m -x wr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_512 -s 512 -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_1k -s 1k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_2k -s 2k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_4k -s 4k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_8k -s 8k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_16k -s 16k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_32k -s 32k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_64k -s 64k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_128k -s 128k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_256k -s 256k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_512k -s 512k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_1m -s 1m -x rdwr
-
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_512 -s 512 -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_1k -s 1k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_2k -s 2k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_4k -s 4k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_8k -s 8k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_16k -s 16k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_32k -s 32k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_64k -s 64k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_128k -s 128k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_256k -s 256k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_512k -s 512k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_1m -s 1m -f $TFILE
-
-.
diff --git a/tools/tests/libMicro/create_stuff.sh b/tools/tests/libMicro/create_stuff.sh
deleted file mode 100755 (executable)
index 7b274cc..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-echo Raising process limits
-echo limit maxproc 1000 2000 >> /etc/launchd.conf
-
-echo Done.
diff --git a/tools/tests/libMicro/dup.c b/tools/tests/libMicro/dup.c
deleted file mode 100644 (file)
index cdce1f1..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * time dup
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/dev/null"
-static char                    *optf = DEFF;
-
-static int                     fd;
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_fds;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-
-       (void) sprintf(lm_optstr, "f:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-dup (default %s)]\n"
-           "notes: measures dup()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(lm_optB * lm_optT + 10);
-       fd = (open(optf, O_RDONLY));
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_fds = (int *)malloc(lm_optB * sizeof (int));
-               if (ts->ts_fds == NULL) {
-                       errors ++;
-               }
-               for (i = 0; i < lm_optB; i++) {
-                       ts->ts_fds[i] = -1;
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_fds[i] = dup(fd);
-               if (ts->ts_fds[i] == -1) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) close(ts->ts_fds[i]);
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/elided.c b/tools/tests/libMicro/elided.c
deleted file mode 100644 (file)
index ab26e6e..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * empty benchmark program to substitute for  benchmarks
- * that don't work/exist on some platforms
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*ARGSUSED*/
-int
-main(int argc, char *argv[])
-{
-       char                     *tmp = strrchr(argv[0], '/');
-
-       if (tmp == NULL)
-               tmp = argv[0];
-       else
-               tmp++;
-
-       (void) printf(
-           "#\n"
-           "# benchmark %s not compiled/supported on this platform\n"
-           "#\n",
-           tmp);
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/embd_bench.sh b/tools/tests/libMicro/embd_bench.sh
deleted file mode 100755 (executable)
index 3abdb43..0000000
+++ /dev/null
@@ -1,815 +0,0 @@
-#!/bin/sh
-#
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-# usage function - defines all the options that can be given to this script.
-function usage {
-       echo "Usage"
-       echo "$0 [-l] [-h] [name of test]"
-       echo "-l               : This option runs the lmbench tests along with the default libmicro tests."
-       echo "-h               : Help. This option displays information on how to run the script. "
-       echo "[name of test]   : This option runs only the test that is specified"
-       echo ""
-       echo "Examples"
-       echo "$0               : This is the defualt execution. This will run only the default libmicro tests."
-       echo "$0 -l            : This will run the lmbench tests too "
-       echo "$0 getppid       : This will run only the getppid tests"
-       exit
-       
-}
-
-if [ $# -eq 1 ]
-then 
-       lmbench=2    # to check if only a single test is to be run. e.g, ./bench.sh getppid
-else
-       lmbench=0    # to run the default libMicro tests, without the lmbench tests.
-fi
-
-while getopts "lh" OPT_LIST
-do
-       case $OPT_LIST in 
-               l) lmbench=1;;    # to run the libmicro tests including the lmbench tests.
-               h) usage;;
-               *) usage;;
-       esac
-done
-
-if [ -w / ]; then
-       #do nothing
-       echo "/ is mounted"
-else
-       echo "ERROR: the test requires that the / directory be read/writable, please mount using the command: 'mount -uw /' "
-       exit 1
-fi
-
-
-tattle="./tattle"
-
-bench_version=0.4.0
-libmicro_version=`$tattle -V`
-
-case $libmicro_version in
-$bench_version)
-       ;;
-*)
-       echo "ERROR: libMicro version doesn't match 'bench' script version"
-       exit 1
-esac
-
-TMPROOT=/private/tmp/libmicro.$$
-VARROOT=/private/var/tmp/libmicro.$$
-mkdir -p $TMPROOT
-mkdir -p $VARROOT
-trap "rm -rf $TMPROOT $VARROOT && exit" 0 2
-
-TFILE=$TMPROOT/data
-IFILE=$TMPROOT/ifile
-TDIR1=$TMPROOT/0/1/2/3/4/5/6/7/8/9
-TDIR2=$TMPROOT/1/2/3/4/5/6/7/8/9/0
-VFILE=$VARROOT/data
-VDIR1=$VARROOT/0/1/2/3/4/5/6/7/8/9
-VDIR2=$VARROOT/1/2/3/4/5/6/7/8/9/0
-
-
-OPTS="-E -C 200 -L -S -W"
-
-dd if=/dev/zero of=$TFILE bs=1024k count=10 2>/dev/null
-dd if=/dev/zero of=$VFILE bs=1024k count=10 2>/dev/null
-mkdir -p $TDIR1 $TDIR2
-mkdir -p $VDIR1 $VDIR2
-
-touch $IFILE
-/usr/bin/touch /private/var/tmp/lmbench
-
-
-# produce benchmark header for easier comparisons
-
-hostname=`uname -n`
-
-if [ -f /usr/sbin/psrinfo ]; then
-       p_count=`psrinfo|wc -l`
-       p_mhz=`psrinfo -v | awk '/operates/{print $6 "MHz"; exit }'`
-       p_type=`psrinfo -vp 2>/dev/null | awk '{if (NR == 3) {print $0; exit}}'` 
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-fi
-
-if [ -f /proc/cpuinfo ]; then
-       p_count=`egrep processor /proc/cpuinfo | wc -l`
-       p_mhz=`awk -F: '/cpu MHz/{printf("%5.0f00Mhz\n",$2/100); exit}' /proc/cpuinfo`
-       p_type=`awk -F: '/model name/{print $2; exit}' /proc/cpuinfo`
-       p_ipaddr=`getent hosts $hostname | awk '{print $1}'`
-else
-## Mac OS X specific stuff
-# first, get ugly output, in case pretty output isn't available
-#
-       p_count=`sysctl -n hw.physicalcpu`
-       p_mhz=`sysctl -n hw.cpufrequency`
-       p_type=`sysctl -n hw.model`
-
-if [ -x /usr/sbin/system_profiler ]; then
-       # <rdar://4655981> requires this hunk of work-around
-       # grep the XML for the characteristic we need. The key appears twice, so grep for the useful key (with 'string')
-       # use sed to strip off the <string></string> and the tabs in front of the string.  So much work for so little result.
-       #
-               p_mhz=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 current_processor_speed | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-               p_type=`system_profiler -xml -detailLevel mini SPHardwareDataType | \
-                       grep -A1 cpu_type | grep string | \
-                       sed -E 's/<string>(.+)<\/string>/\1/' | sed 's- --g'`
-fi
-
-# look for en0 (usually ethernet) if that isn't there try en1 (usually wireless) else give up
-       p_ipaddr=`ipconfig getpacket en0 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       if [ ! $p_ipaddr  ]; then
-               p_ipaddr=`ipconfig getpacket en1 | grep yiaddr | tr "= " "\n" | grep [0-9]`
-       elif [ ! $p_ipaddr ]; then
-               p_ipaddr="unknown"
-       fi
-fi
-
-printf "\n\n!Libmicro_#:   %30s\n" $libmicro_version
-printf "!Options:      %30s\n" "$OPTS"
-printf "!Machine_name: %30s\n" "$hostname"
-printf "!OS_name:      %30s\n" `uname -s`
-printf "!OS_release:   %30s\n" `sw_vers -productVersion`
-printf "!OS_build:     %30.18s\n" "`sw_vers -buildVersion`"
-printf "!Processor:    %30s\n" `arch`
-printf "!#CPUs:        %30s\n" $p_count
-printf "!CPU_MHz:      %30s\n" "$p_mhz"
-printf "!CPU_NAME:     %30s\n" "$p_type"
-printf "!IP_address:   %30s\n" "$p_ipaddr"
-printf "!Run_by:       %30s\n" $LOGNAME
-printf "!Date:        %30s\n" "`date '+%D %R'`"
-printf "!Compiler:     %30s\n" `$tattle -c`
-printf "!Compiler Ver.:%30s\n" "`$tattle -v`"
-printf "!sizeof(long): %30s\n" `$tattle -s`
-printf "!extra_CFLAGS: %30s\n" "`$tattle -f`"
-printf "!TimerRes:     %30s\n\n\n" "`$tattle -r`"
-bin_dir="$TMPROOT/bin"
-
-mkdir -p $bin_dir
-cp bin-*/exec_bin $bin_dir/$A
-
-cp ./apple/bin-*/posix_spawn_bin $bin_dir/$A
-
-newline=0
-
-#
-# Everything below the while loop is input for the while loop if
-# you have any tests which can't run in the while loop, put
-# them above this comment
-#
-while read A B
-do
-       # $A contains the command, $B contains the arguments
-       # we echo blank lines and comments
-       # we skip anything which fails to match *$1* (useful if
-       # we only want to test one case, but a nasty hack)
-
-       case $A in
-       \#*)
-               echo "$A $B"
-               newline=1
-               continue
-               ;;
-       
-       "")
-               if [ $newline -eq 1 ]
-               then
-                       newline=0
-                       echo
-                       echo
-               fi
-
-               continue
-               ;;
-
-       *$1*)
-               # Default execution without the lmbench tests. 
-               # checks if there is no argument passed by the user.
-               if [  $lmbench -eq 0 ]
-               then
-                       string=lmbench
-                       if [ "${A:0:7}" == "$string" ]
-                       then
-                               continue
-                       fi
-               fi
-                       
-               ;;
-       
-       *)              
-               if [ $lmbench -ne 1 ]
-               then
-                       continue
-               fi
-               ;;
-       esac
-
-       if [ ! -f $bin_dir/$A ]
-       then
-               cp bin-*/$A $bin_dir/$A
-       fi
-
-       echo
-
-       (cd $TMPROOT && eval "bin/$A $B")
-
-       echo
-       echo
-done <<.
-
-#
-# Obligatory null system call: use very short time
-# for default since SuSe implements this "syscall" in userland
-#
-
-getpid         $OPTS -N "getpid" -I 5
-getppid                $OPTS -N "getppid" -I 5
-
-getenv         $OPTS -N "getenv"       -s 100 -I 100    
-getenv         $OPTS -N "getenvT2"     -s 100 -I 100   -T 2 
-
-gettimeofday   $OPTS -N "gettimeofday"          
-
-log            $OPTS -N "log"  -I 20   -B 300000        
-exp            $OPTS -N "exp"  -I 20   -B 100000        
-lrand48                $OPTS -N "lrand48"
-
-memset         $OPTS -N "memset_10"    -s 10   -I 10 
-memset         $OPTS -N "memset_256"   -s 256  -I 20
-memset         $OPTS -N "memset_256_u" -s 256   -a 1 -I 20 
-memset         $OPTS -N "memset_1k"    -s 1k    -I 100 -B 2000
-memset         $OPTS -N "memset_4k"    -s 4k    -I 250 -B 500
-memset         $OPTS -N "memset_4k_uc" -s 4k    -u -I 400
-
-memset         $OPTS -N "memset_10k"   -s 10k  -I 600 -B 500
-memset         $OPTS -N "memset_1m"    -s 1m   -I 200000
-memset         $OPTS -N "memset_10m"   -s 10m -I 2000000 
-memset         $OPTS -N "memsetP2_10m" -s 10m -P 2 -I 2000000 
-
-memrand                $OPTS -N "memrand"      -s 40m -B 10000
-
-# This is an elided test and is not ported yet.
-# Check Makefile.darwin for list of elided tests  
-# cachetocache $OPTS -N "cachetocache" -s 100k -T 2 -I 200
-
-isatty         $OPTS -N "isatty_yes"   
-isatty         $OPTS -N "isatty_no"  -f $IFILE
-
-malloc         $OPTS -N "malloc_10"    -s 10    -g 10 -I 50
-malloc         $OPTS -N "malloc_100"   -s 100   -g 10 -I 50
-malloc         $OPTS -N "malloc_1k"    -s 1k    -g 10 -I 50
-malloc         $OPTS -N "malloc_10k"   -s 10k   -g 10 -I 50
-malloc         $OPTS -N "malloc_100k"  -s 100k  -g 10 -I 2000
-
-malloc         $OPTS -N "mallocT2_10"    -s 10   -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_100"   -s 100  -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_1k"    -s 1k   -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_10k"   -s 10k  -g 10 -T 2 -I 200
-malloc         $OPTS -N "mallocT2_100k"  -s 100k -g 10 -T 2 -I 10000
-
-close          $OPTS -N "close_bad"            -B 96           -b
-close          $OPTS -N "close_tmp"            -B 64           -f $TFILE
-close          $OPTS -N "close_usr"            -B 64           -f $VFILE
-close          $OPTS -N "close_zero"           -B 64           -f /dev/zero
-close_tcp      $OPTS -N "close_tcp"            -B 32  
-
-memcpy         $OPTS -N "memcpy_10"    -s 10   -I 10 
-memcpy         $OPTS -N "memcpy_1k"    -s 1k   -I 50
-memcpy         $OPTS -N "memcpy_10k"   -s 10k  -I 800
-memcpy         $OPTS -N "memcpy_1m"    -s 1m   -I 500000
-memcpy         $OPTS -N "memcpy_10m"   -s 10m  -I 5000000
-
-strcpy         $OPTS -N "strcpy_10"    -s 10   -I 5 
-strcpy         $OPTS -N "strcpy_1k"    -s 1k   -I 100
-
-strlen         $OPTS -N "strlen_10"    -s 10   -I 5
-strlen         $OPTS -N "strlen_1k"    -s 1k   -I 100
-
-strchr         $OPTS -N "strchr_10"    -s 10   -I 5
-strchr         $OPTS -N "strchr_1k"    -s 1k   -I 200
-strcmp         $OPTS -N "strcmp_10"    -s 10   -I 10
-strcmp         $OPTS -N "strcmp_1k"    -s 1k   -I 200
-
-strcasecmp     $OPTS -N "scasecmp_10"  -s 10 -I 50 -B 2000
-strcasecmp     $OPTS -N "scasecmp_1k"  -s 1k -I 20000 -B 100
-
-strtol         $OPTS -N "strtol"      -I 20      
-
-# This is an elided test and is not ported yet.     
-# Check Makefile.darwin for list of elided tests
-# getcontext   $OPTS -N "getcontext"  -I 100
-
-# This is an elided test and is not ported yet.     
-# Check Makefile.darwin for list of elided tests
-# setcontext   $OPTS -N "setcontext"  -I 100
-
-mutex          $OPTS -N "mutex_st"     -I 10
-mutex          $OPTS -N "mutex_mt"     -t -I 10        
-mutex          $OPTS -N "mutex_T2"     -T 2  -I 100
-
-longjmp                $OPTS -N "longjmp"      -I 10
-siglongjmp     $OPTS -N "siglongjmp"   -I 20
-
-getrusage      $OPTS -N "getrusage"    -I 200
-
-times          $OPTS -N "times"        -I 200
-time           $OPTS -N "time"         -I 50
-localtime_r    $OPTS -N "localtime_r"  -I 200  
-strftime       $OPTS -N "strftime" -I 10000 -B 100 
-
-mktime         $OPTS -N "mktime"       -I 500   
-mktime         $OPTS -N "mktimeT2" -T 2 -I 1000 
-
-cascade_mutex  $OPTS -N "c_mutex_1"    -I 50
-cascade_mutex  $OPTS -N "c_mutex_10"   -T 10 -I 5000
-cascade_mutex  $OPTS -N "c_mutex_200"  -T 200  -I 2000000
-
-cascade_cond   $OPTS -N "c_cond_1"     -I 100
-cascade_cond   $OPTS -N "c_cond_10"    -T 10   -I 3000
-cascade_cond   $OPTS -N "c_cond_200"   -T 200  -I 2000000
-
-cascade_lockf  $OPTS -N "c_lockf_1"    -I 1000 
-cascade_lockf  $OPTS -N "c_lockf_10"   -P 10 -I 50000
-#cascade_lockf $OPTS -N "c_lockf_200"  -P 200 -I 5000000
-
-
-
-cascade_flock  $OPTS -N "c_flock"      -I 1000 
-cascade_flock  $OPTS -N "c_flock_10"   -P 10   -I 50000
-#cascade_flock $OPTS -N "c_flock_200"  -P 200  -I 5000000
-
-
-
-cascade_fcntl  $OPTS -N "c_fcntl_1"    -I 2000         
-cascade_fcntl  $OPTS -N "c_fcntl_10"   -P 10 -I 20000
-#cascade_fcntl $OPTS -N "c_fcntl_200"  -P 200  -I 5000000
-
-
-file_lock      $OPTS -N "file_lock"   -I 1000         
-
-getsockname    $OPTS -N "getsockname"  -I 100
-getpeername    $OPTS -N "getpeername"  -I 100
-
-chdir          $OPTS -N "chdir_tmp"    -I 2000         $TDIR1 $TDIR2
-chdir          $OPTS -N "chdir_usr"    -I 2000         $VDIR1 $VDIR2
-
-chdir          $OPTS -N "chgetwd_tmp"  -I 3000 -g $TDIR1 $TDIR2
-chdir          $OPTS -N "chgetwd_usr"  -I 3000 -g $VDIR1 $VDIR2
-
-realpath       $OPTS -N "realpath_tmp" -I 3000         -f $TDIR1
-realpath       $OPTS -N "realpath_usr" -I 3000 -f $VDIR1
-
-stat           $OPTS -N "stat_tmp" -I 1000             -f $TFILE
-stat           $OPTS -N "stat_usr" -I 1000             -f $VFILE
-
-lmbench_stat           $OPTS -N "lmbench_stat_tmp" -I 1000             -f $TFILE
-lmbench_stat           $OPTS -N "lmbench_stat_usr" -I 10000 -B 100             -f /private/var/tmp/lmbench
-
-#
-# lmbench uses a touched empty file in /private/var/tmp
-# libMicro uses a 1M file in a directory off /private/var/tmp
-# performance difference is ~ 0.2 usecs/call
-#
-# why? - walking the dir tree, empty file vs. non-empty file, non-empty dir
-# in the case of libMicro, etc., etc.
-#
-
-lmbench_stat           $OPTS -N "lmbench_stat_usr - Default" -I 10000 -B 100   -f /private/var/tmp/lmbench
-
-lmbench_fstat          $OPTS -N "lmbench_fstat_tmp" -I 1000            -f $TFILE
-lmbench_fstat          $OPTS -N "lmbench_fstat_usr" -I 10000 -B 100            -f /private/var/tmp/lmbench
-
-# see stat test to understand why we are using /private/var/tmp/lmbench
-
-lmbench_fstat          $OPTS -N "lmbench_fstat_usr - Default" -I 10000 -B 100  -f /private/var/tmp/lmbench
-
-lmbench_openclose      $OPTS -N "lmbench_openclose - Default" -I 10000 -B 100  -f /private/var/tmp/lmbench
-
-lmbench_select_file $OPTS -N "lmbench_select_file_10"  -n 10  -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_100" -n 100 -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_250" -n 250 -B 100
-lmbench_select_file $OPTS -N "lmbench_select_file_500" -n 500 -B 100
-
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_10"  -n 10  -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_100" -n 100 -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_250" -n 250 -B 100
-lmbench_select_tcp $OPTS -N "lmbench_select_tcp_500" -n 500 -B 100
-
-fcntl          $OPTS -N "fcntl_tmp"    -I 100  -f $TFILE
-fcntl          $OPTS -N "fcntl_usr"    -I 100  -f $VFILE
-fcntl_ndelay   $OPTS -N "fcntl_ndelay" -I 100  
-
-lseek          $OPTS -N "lseek_t8k"    -s 8k   -I 50   -f $TFILE
-lseek          $OPTS -N "lseek_u8k"    -s 8k   -I 50   -f $VFILE
-
-open           $OPTS -N "open_tmp"             -B 256          -f $TFILE
-open           $OPTS -N "open_usr"             -B 256          -f $VFILE
-open           $OPTS -N "open_zero"            -B 256          -f /dev/zero
-
-dup            $OPTS -N "dup"                  -B 512   
-
-socket         $OPTS -N "socket_u"             -B 256
-socket         $OPTS -N "socket_i"             -B 256          -f PF_INET
-
-socketpair     $OPTS -N "socketpair"           -B 256
-
-setsockopt     $OPTS -N "setsockopt"           -I 200
-
-bind           $OPTS -N "bind"                 -B 100
-
-listen         $OPTS -N "listen"               -B 100
-
-#connection    $OPTS -N "connection"           -B 256 
-
-poll           $OPTS -N "poll_10"      -n 10   -I 500
-poll           $OPTS -N "poll_100"     -n 100  -I 1000
-poll           $OPTS -N "poll_1000"    -n 1000 -I 5000
-
-poll           $OPTS -N "poll_w10"     -n 10   -I 500          -w 1
-poll           $OPTS -N "poll_w100"    -n 100  -I 2000         -w 10
-poll           $OPTS -N "poll_w1000"   -n 1000 -I 40000        -w 100
-
-select         $OPTS -N "select_10"    -n 10   -I 500
-select         $OPTS -N "select_100"   -n 100  -I 1000
-select         $OPTS -N "select_1000"  -n 1000 -I 5000
-
-select         $OPTS -N "select_w10"   -n 10   -I 500          -w 1
-select         $OPTS -N "select_w100"  -n 100  -I 2000         -w 10
-select         $OPTS -N "select_w1000" -n 1000 -I 40000        -w 100
-
-semop          $OPTS -N "semop" -I 200
-
-sigaction      $OPTS -N "sigaction" -I 100
-signal         $OPTS -N "signal" -I 1000
-sigprocmask    $OPTS -N "sigprocmask" -I 200
-
-lmbench_lat_sig_install        $OPTS -N "lmbench_siginstall"
-# sigcatch and sigsend need to be evaluated together
-# lmbench framework will allow multiple measurements within the same
-# benchmark test which allow them to factor out the cost of sending
-# a signal from catching one
-#
-# for our purposes sigcatch results - sigsend results yield
-# lmbench sig handler overhead measurements
-lmbench_lat_sig_catch  $OPTS -N "lmbench_sigcatch" 
-lmbench_lat_sig_send   $OPTS -N "lmbench_sigsend" 
-
-
-pthread_create  $OPTS -N "pthread_8"           -B 8
-pthread_create  $OPTS -N "pthread_32"          -B 32
-pthread_create  $OPTS -N "pthread_128"         -B 128
-pthread_create  $OPTS -N "pthread_512"         -B 512
-
-fork           $OPTS -N "fork_10"              -B 10
-#fork          $OPTS -N "fork_100"             -B 100  -C 100
-
-#fork          $OPTS -N "fork_1000"            -B 1000 -C 50
-
-exit           $OPTS -N "exit_10"              -B 10
-##exit         $OPTS -N "exit_100"             -B 100
-
-#exit          $OPTS -N "exit_1000"            -B 1000 -C 50
-
-exit           $OPTS -N "exit_10_nolibc"       -e -B 10
-
-exec           $OPTS -N "exec" -B 10
-
-posix_spawn    $OPTS -N "posix_spawn" -B 10
-
-system         $OPTS -N "system" -I 1000000
-
-recurse                $OPTS -N "recurse"              -B 512
-
-read           $OPTS -N "read_t1k"     -s 1k -B 50                     -f $TFILE
-read           $OPTS -N "read_t10k"    -s 10k  -B 16           -f $TFILE
-read           $OPTS -N "read_t100k"   -s 100k -B 4            -f $TFILE
-
-read           $OPTS -N "read_u1k"     -s 1k   -B 50           -f $VFILE
-read           $OPTS -N "read_u10k"    -s 10k  -B 16           -f $VFILE
-read           $OPTS -N "read_u100k"   -s 100k -B 4            -f $VFILE
-
-read           $OPTS -N "read_z1k"     -s 1k   -B 100          -f /dev/zero 
-read           $OPTS -N "read_z10k"    -s 10k  -B 30           -f /dev/zero 
-read           $OPTS -N "read_z100k"   -s 100k -B 4            -f /dev/zero 
-read           $OPTS -N "read_zw100k"  -s 100k -B 4         -w -f /dev/zero 
-
-lmbench_read           $OPTS -N "read_t1b"     -s 1 -B 50                      -f $TFILE
-lmbench_read           $OPTS -N "read_t1k"     -s 1k -B 50                     -f $TFILE
-lmbench_read           $OPTS -N "read_t10k"    -s 10k  -B 16           -f $TFILE
-lmbench_read           $OPTS -N "read_t100k"   -s 100k -B 4            -f $TFILE
-
-lmbench_read           $OPTS -N "read_u1b"     -s 1    -B 50           -f $VFILE
-lmbench_read           $OPTS -N "read_u1k"     -s 1k   -B 50           -f $VFILE
-lmbench_read           $OPTS -N "read_u10k"    -s 10k  -B 16           -f $VFILE
-lmbench_read           $OPTS -N "read_u100k"   -s 100k -B 4            -f $VFILE
-
-lmbench_read           $OPTS -N "read_z1b - Default"   -s 1    -B 100          -f /dev/zero 
-lmbench_read           $OPTS -N "read_z1k"     -s 1k   -B 100          -f /dev/zero 
-lmbench_read           $OPTS -N "read_z10k"    -s 10k  -B 30           -f /dev/zero 
-lmbench_read           $OPTS -N "read_z100k"   -s 100k -B 4            -f /dev/zero 
-lmbench_read           $OPTS -N "read_zw100k"  -s 100k -B 4         -w -f /dev/zero 
-
-write          $OPTS -N "write_t1k"    -s 1k   -B 50           -f $TFILE
-write          $OPTS -N "write_t10k"   -s 10k  -B 25           -f $TFILE
-write          $OPTS -N "write_t100k"  -s 100k -B 4            -f $TFILE
-
-write          $OPTS -N "write_u1k"    -s 1k   -B 50           -f $VFILE
-write          $OPTS -N "write_u10k"   -s 10k  -B 25           -f $VFILE
-write          $OPTS -N "write_u100k"  -s 100k -B 4            -f $VFILE
-
-write          $OPTS -N "write_n1k"    -s 1k   -I 100 -B 0     -f /dev/null 
-write          $OPTS -N "write_n10k"   -s 10k  -I 100 -B 0     -f /dev/null 
-write          $OPTS -N "write_n100k"  -s 100k -I 100 -B 0     -f /dev/null 
-
-lmbench_write          $OPTS -N "lmbench_write_t1b"    -s 1    -B 50           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t1k"    -s 1k   -B 50           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t10k"   -s 10k  -B 25           -f $TFILE
-lmbench_write          $OPTS -N "lmbench_write_t100k"  -s 100k -B 4            -f $TFILE
-
-lmbench_write          $OPTS -N "lmbench_write_u1b"    -s 1    -B 50           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u1k"    -s 1k   -B 50           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u10k"   -s 10k  -B 25           -f $VFILE
-lmbench_write          $OPTS -N "lmbench_write_u100k"  -s 100k -B 4            -f $VFILE
-
-lmbench_write          $OPTS -N "lmbench_write_n1b - Default"  -s 1    -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n1k"    -s 1k   -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n10k"   -s 10k  -I 100 -B 0     -f /dev/null 
-lmbench_write          $OPTS -N "lmbench_write_n100k"  -s 100k -I 100 -B 0     -f /dev/null 
-
-writev         $OPTS -N "writev_t1k"   -s 1k   -B 20           -f $TFILE
-writev         $OPTS -N "writev_t10k"  -s 10k  -B 4            -f $TFILE
-writev         $OPTS -N "writev_t100k" -s 100k                 -f $TFILE
-
-writev         $OPTS -N "writev_u1k"   -s 1k   -B 20           -f $VFILE
-writev         $OPTS -N "writev_u10k"  -s 10k  -B 4            -f $VFILE
-writev         $OPTS -N "writev_u100k" -s 100k                 -f $VFILE
-
-writev         $OPTS -N "writev_n1k"   -s 1k   -I 100 -B 0     -f /dev/null 
-writev         $OPTS -N "writev_n10k"  -s 10k  -I 100 -B 0     -f /dev/null 
-writev         $OPTS -N "writev_n100k" -s 100k -I 100 -B 0     -f /dev/null 
-
-pread          $OPTS -N "pread_t1k"    -s 1k   -I 300          -f $TFILE
-pread          $OPTS -N "pread_t10k"   -s 10k  -I 1000         -f $TFILE
-pread          $OPTS -N "pread_t100k"  -s 100k -I 10000        -f $TFILE
-
-pread          $OPTS -N "pread_u1k"    -s 1k   -I 300          -f $VFILE
-pread          $OPTS -N "pread_u10k"   -s 10k  -I 1000         -f $VFILE
-pread          $OPTS -N "pread_u100k"  -s 100k -I 10000        -f $VFILE
-
-pread          $OPTS -N "pread_z1k"    -s 1k   -I 300          -f /dev/zero 
-pread          $OPTS -N "pread_z10k"   -s 10k  -I 1000         -f /dev/zero 
-pread          $OPTS -N "pread_z100k"  -s 100k -I 2000 -f /dev/zero 
-pread          $OPTS -N "pread_zw100k" -s 100k -w -I 10000     -f /dev/zero 
-
-pwrite         $OPTS -N "pwrite_t1k"   -s 1k   -I 500          -f $TFILE
-pwrite         $OPTS -N "pwrite_t10k"  -s 10k  -I 1000         -f $TFILE
-pwrite         $OPTS -N "pwrite_t100k" -s 100k -I 10000        -f $TFILE
-
-pwrite         $OPTS -N "pwrite_u1k"   -s 1k   -I 500          -f $VFILE
-pwrite         $OPTS -N "pwrite_u10k"  -s 10k  -I 1000         -f $VFILE
-pwrite         $OPTS -N "pwrite_u100k" -s 100k -I 20000        -f $VFILE
-
-pwrite         $OPTS -N "pwrite_n1k"   -s 1k   -I 100          -f /dev/null 
-pwrite         $OPTS -N "pwrite_n10k"  -s 10k  -I 100          -f /dev/null 
-pwrite         $OPTS -N "pwrite_n100k" -s 100k -I 100          -f /dev/null 
-
-
-mmap           $OPTS -N "mmap_t8k"     -l 8k   -I 1000         -f $TFILE
-mmap           $OPTS -N "mmap_t128k"   -l 128k -I 1000         -f $TFILE
-mmap           $OPTS -N "mmap_u8k"     -l 8k   -I 1000         -f $VFILE
-mmap           $OPTS -N "mmap_u128k"   -l 128k -I 1000         -f $VFILE
-mmap           $OPTS -N "mmap_a8k"     -l 8k   -I 200          -f MAP_ANON
-mmap           $OPTS -N "mmap_a128k"   -l 128k -I 200          -f MAP_ANON
-
-
-
-mmap           $OPTS -N "mmap_rt8k"    -l 8k   -I 2000 -r      -f $TFILE
-mmap           $OPTS -N "mmap_rt128k"  -l 128k -I 20000 -r     -f $TFILE
-mmap           $OPTS -N "mmap_ru8k"    -l 8k   -I 2000 -r      -f $VFILE
-mmap           $OPTS -N "mmap_ru128k"  -l 128k -I 20000 -r     -f $VFILE
-mmap           $OPTS -N "mmap_ra8k"    -l 8k   -I 2000 -r      -f MAP_ANON
-mmap           $OPTS -N "mmap_ra128k"  -l 128k -I 20000 -r     -f MAP_ANON
-
-
-mmap           $OPTS -N "mmap_wt8k"    -l 8k   -I 5000 -w      -f $TFILE
-mmap           $OPTS -N "mmap_wt128k"  -l 128k -I 50000 -w     -f $TFILE
-mmap           $OPTS -N "mmap_wu8k"    -l 8k   -I 5000 -w      -f $VFILE
-mmap           $OPTS -N "mmap_wu128k"  -l 128k -I 500000 -w    -f $VFILE
-mmap           $OPTS -N "mmap_wa8k"    -l 8k   -I 3000 -w      -f MAP_ANON
-mmap           $OPTS -N "mmap_wa128k"  -l 128k -I 50000 -w     -f MAP_ANON
-
-
-munmap         $OPTS -N "unmap_t8k"    -l 8k   -I 500          -f $TFILE
-munmap         $OPTS -N "unmap_t128k"  -l 128k -I 500          -f $TFILE
-munmap         $OPTS -N "unmap_u8k"    -l 8k   -I 500          -f $VFILE
-munmap         $OPTS -N "unmap_u128k"  -l 128k -I 500          -f $VFILE
-munmap         $OPTS -N "unmap_a8k"    -l 8k   -I 500          -f MAP_ANON
-munmap         $OPTS -N "unmap_a128k"  -l 128k -I 500          -f MAP_ANON
-
-
-munmap         $OPTS -N "unmap_rt8k"   -l 8k   -I 1000 -r      -f $TFILE
-munmap         $OPTS -N "unmap_rt128k" -l 128k -I 3000 -r      -f $TFILE
-munmap         $OPTS -N "unmap_ru8k"   -l 8k   -I 1000 -r      -f $VFILE
-munmap         $OPTS -N "unmap_ru128k" -l 128k -I 3000 -r      -f $VFILE
-munmap         $OPTS -N "unmap_ra8k"   -l 8k   -I 1000 -r      -f MAP_ANON
-munmap         $OPTS -N "unmap_ra128k" -l 128k -I 2000 -r      -f MAP_ANON
-
-connection     $OPTS -N "conn_connect"         -B 256  -c
-
-
-munmap         $OPTS -N "unmap_wt8k"   -l 8k   -I 1000 -w      -f $TFILE
-munmap         $OPTS -N "unmap_wt128k" -l 128k -I 10000        -w      -f $TFILE
-munmap         $OPTS -N "unmap_wu8k"   -l 8k   -I 1000 -w      -f $VFILE
-munmap         $OPTS -N "unmap_wu128k" -l 128k -I 50000        -w -B 10        -f $VFILE
-munmap         $OPTS -N "unmap_wa8k"   -l 8k   -I 1000 -w      -f MAP_ANON
-munmap         $OPTS -N "unmap_wa128k" -l 128k -I 10000        -w      -f MAP_ANON
-
-mprotect       $OPTS -N "mprot_z8k"    -l 8k  -I 300                   -f /dev/zero
-mprotect       $OPTS -N "mprot_z128k"  -l 128k -I 500          -f /dev/zero
-mprotect       $OPTS -N "mprot_wz8k"   -l 8k   -I 500  -w      -f /dev/zero
-mprotect       $OPTS -N "mprot_wz128k" -l 128k -I 1000 -w      -f /dev/zero
-mprotect       $OPTS -N "mprot_twz8k"  -l 8k   -I 1000 -w -t   -f /dev/zero
-mprotect       $OPTS -N "mprot_tw128k" -l 128k -I 2000 -w -t   -f /dev/zero
-mprotect       $OPTS -N "mprot_tw4m"   -l 4m   -w -t -B 1  -f /dev/zero
-
-pipe           $OPTS -N "pipe_pst1"    -s 1    -I 1000 -x pipe -m st
-pipe           $OPTS -N "pipe_pmt1"    -s 1    -I 8000 -x pipe -m mt
-pipe           $OPTS -N "pipe_pmp1"    -s 1    -I 8000 -x pipe -m mp
-pipe           $OPTS -N "pipe_pst4k"   -s 4k   -I 1000 -x pipe -m st
-pipe           $OPTS -N "pipe_pmt4k"   -s 4k   -I 8000 -x pipe -m mt
-pipe           $OPTS -N "pipe_pmp4k"   -s 4k   -I 8000 -x pipe -m mp
-
-pipe           $OPTS -N "pipe_sst1"    -s 1    -I 1000 -x sock -m st
-pipe           $OPTS -N "pipe_smt1"    -s 1    -I 8000 -x sock -m mt
-pipe           $OPTS -N "pipe_smp1"    -s 1    -I 8000 -x sock -m mp
-pipe           $OPTS -N "pipe_sst4k"   -s 4k   -I 1000 -x sock -m st
-pipe           $OPTS -N "pipe_smt4k"   -s 4k   -I 8000 -x sock -m mt
-pipe           $OPTS -N "pipe_smp4k"   -s 4k   -I 8000 -x sock -m mp
-
-pipe           $OPTS -N "pipe_tst1"    -s 1    -I 1000 -x tcp  -m st
-pipe           $OPTS -N "pipe_tmt1"    -s 1    -I 8000 -x tcp  -m mt
-pipe           $OPTS -N "pipe_tmp1"    -s 1    -I 8000 -x tcp  -m mp
-pipe           $OPTS -N "pipe_tst4k"   -s 4k   -I 1000 -x tcp  -m st
-pipe           $OPTS -N "pipe_tmt4k"   -s 4k   -I 8000 -x tcp  -m mt
-pipe           $OPTS -N "pipe_tmp4k"   -s 4k   -I 8000 -x tcp  -m mp
-
-#connection    $OPTS -N "conn_accept"          -B 256      -a
-
-lmbench_bw_unix -B 11 -L -W
-
-lmbench_bw_mem $OPTS -N lmbench_bcopy_512 -s 512 -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_1k -s 1k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_2k -s 2k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_4k -s 4k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_8k -s 8k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_16k -s 16k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_32k -s 32k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_64k -s 64k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_128k -s 128k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_256k -s 256k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_512k -s 512k -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bcopy_1m -s 1m -x bcopy
-lmbench_bw_mem $OPTS -N lmbench_bzero_512 -s 512 -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_1k -s 1k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_2k -s 2k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_4k -s 4k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_8k -s 8k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_16k -s 16k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_32k -s 32k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_64k -s 64k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_128k -s 128k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_256k -s 256k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_512k -s 512k -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_1m -s 1m -x bzero
-lmbench_bw_mem $OPTS -N lmbench_bzero_512 -s 512 -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_1k -s 1k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_2k -s 2k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_4k -s 4k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_8k -s 8k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_16k -s 16k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_32k -s 32k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_64k -s 64k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_128k -s 128k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_256k -s 256k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_512k -s 512k -x fcp
-lmbench_bw_mem $OPTS -N lmbench_bzero_1m -s 1m -x fcp
-lmbench_bw_mem $OPTS -N lmbench_cp_512 -s 512 -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_1k -s 1k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_2k -s 2k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_4k -s 4k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_8k -s 8k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_16k -s 16k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_32k -s 32k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_64k -s 64k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_128k -s 128k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_256k -s 256k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_512k -s 512k -x cp
-lmbench_bw_mem $OPTS -N lmbench_cp_1m -s 1m -x cp
-lmbench_bw_mem $OPTS -N lmbench_frd_512 -s 512 -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_1k -s 1k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_2k -s 2k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_4k -s 4k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_8k -s 8k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_16k -s 16k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_32k -s 32k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_64k -s 64k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_128k -s 128k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_256k -s 256k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_512k -s 512k -x frd
-lmbench_bw_mem $OPTS -N lmbench_frd_1m -s 1m -x frd
-lmbench_bw_mem $OPTS -N lmbench_rd_512 -s 512 -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_1k -s 1k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_2k -s 2k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_4k -s 4k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_8k -s 8k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_16k -s 16k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_32k -s 32k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_64k -s 64k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_128k -s 128k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_256k -s 256k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_512k -s 512k -x rd
-lmbench_bw_mem $OPTS -N lmbench_rd_1m -s 1m -x rd
-lmbench_bw_mem $OPTS -N lmbench_fwr_512 -s 512 -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_1k -s 1k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_2k -s 2k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_4k -s 4k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_8k -s 8k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_16k -s 16k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_32k -s 32k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_64k -s 64k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_128k -s 128k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_256k -s 256k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_512k -s 512k -x fwr
-lmbench_bw_mem $OPTS -N lmbench_fwr_1m -s 1m -x fwr
-lmbench_bw_mem $OPTS -N lmbench_wr_512 -s 512 -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_1k -s 1k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_2k -s 2k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_4k -s 4k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_8k -s 8k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_16k -s 16k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_32k -s 32k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_64k -s 64k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_128k -s 128k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_256k -s 256k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_512k -s 512k -x wr
-lmbench_bw_mem $OPTS -N lmbench_wr_1m -s 1m -x wr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_512 -s 512 -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_1k -s 1k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_2k -s 2k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_4k -s 4k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_8k -s 8k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_16k -s 16k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_32k -s 32k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_64k -s 64k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_128k -s 128k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_256k -s 256k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_512k -s 512k -x rdwr
-lmbench_bw_mem $OPTS -N lmbench_rdwr_1m -s 1m -x rdwr
-
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_512 -s 512 -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_1k -s 1k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_2k -s 2k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_4k -s 4k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_8k -s 8k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_16k -s 16k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_32k -s 32k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_64k -s 64k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_128k -s 128k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_256k -s 256k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_512k -s 512k -f $TFILE
-lmbench_bw_mmap_rd $OPTS -N bw_mmap_rd_1m -s 1m -f $TFILE
-
-.
diff --git a/tools/tests/libMicro/exec.c b/tools/tests/libMicro/exec.c
deleted file mode 100644 (file)
index 3110a14..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * exec benchmark
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-
-#include "libmicro.h"
-
-static char exec_path[1024];
-static char *argv[3];
-
-int
-benchmark_init()
-{
-       lm_defB = 128;
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "notes: measures execv time of simple process()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_initbatch(void *tsd)
-{
-       char                    buffer[80];
-
-       (void) strcpy(exec_path, lm_procpath);
-       (void) strcat(exec_path, "/exec_bin");
-
-       (void) sprintf(buffer, "%d", lm_optB);
-       argv[0] = exec_path;
-       argv[1] = strdup(buffer);
-       argv[2] = NULL;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int c;
-       int status;
-
-       switch (c = fork()) {
-       case -1:
-               res->re_errors++;
-               break;
-       default:
-               if (waitpid(c, &status, 0) < 0)
-                       res->re_errors++;
-
-               if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
-                       res->re_errors++;
-               break;
-       case 0:
-               if (execv(exec_path, argv) < 0)
-                       res->re_errors++;
-       }
-
-       res->re_count = lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/exec_bin.c b/tools/tests/libMicro/exec_bin.c
deleted file mode 100644 (file)
index 4cddfd3..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * time program to recursively test exec time
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int
-main(int argc, char *argv[])
-{
-       int left;
-
-       if (argc == 1) {
-               exit(1);
-       }
-
-       left = atoi(argv[1]);
-
-       left--;
-
-       if (left <= 0) {
-               exit(0);
-       } else {
-               char buffer[80];
-               (void) sprintf(buffer, "%d", left);
-               argv[1] = buffer;
-               if (execv(argv[0], argv)) {
-                       exit(2);
-               }
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/exit.c b/tools/tests/libMicro/exit.c
deleted file mode 100644 (file)
index e2aa54d..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark exit
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_pids;
-} tsd_t;
-
-static int                     opte = 0;
-static barrier_t               *b;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-       (void) sprintf(lm_optstr, "e");
-
-       (void) sprintf(lm_usage,
-           "       [-e] (uses _exit() rather than exit())"
-           "notes: measures exit()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'e':
-               opte = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       b = barrier_create(lm_optP * lm_optT * (lm_optB + 1), 0);
-
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       (void) barrier_destroy(b);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_pids = (int *)malloc(lm_optB * sizeof (pid_t));
-               if (ts->ts_pids == NULL) {
-                       errors ++;
-               }
-       }
-
-       /*
-        * create processes to exit
-        */
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_pids[i] = fork();
-               switch (ts->ts_pids[i]) {
-               case 0:
-                       (void) barrier_queue(b, NULL);
-                       if (opte)
-                               _exit(0);
-                       exit(0);
-                       break;
-               case -1:
-                       errors ++;
-                       break;
-               default:
-                       continue;
-               }
-       }
-
-       return (errors);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       /*
-        * start them all exiting
-        */
-
-       (void) barrier_queue(b, NULL);
-
-       /*
-        * wait for them all to exit
-        */
-
-       for (i = 0; i < lm_optB; i++) {
-               switch (waitpid((pid_t)-1, NULL, 0)) {
-               case 0:
-                       continue;
-               case -1:
-                       res->re_errors++;
-               }
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/exp.c b/tools/tests/libMicro/exp.c
deleted file mode 100644 (file)
index 14ad80b..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * test exp performance (should add range check)
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures exp()");
-       lm_nsecs_per_op = 25;
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       /* Added as part of the fix for radar 7508837 */
-        double                  t = 0.0;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               double value = 1.0 / (i + .01);
-#if 1 /* Apple added code, see radar 7508837 */
-                t += exp(value);
-                t += exp(value + 1.0);
-                t += exp(value + 2.0);
-                t += exp(value + 3.0);
-                t += exp(value + 4.0);
-                t += exp(value + 5.0);
-                t += exp(value + 6.0);
-                t += exp(value + 7.0);
-                t += exp(value + 8.0);
-                t += exp(value + 9.0);
-        }
-        res->re_count = i;
-
-        return ((int)(t - t));
-#else
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-               (void) exp(value);
-       }
-       res->re_count = i;
-
-       return (0);
-#endif /* end of Apple fix  */
-}
diff --git a/tools/tests/libMicro/fcntl.c b/tools/tests/libMicro/fcntl.c
deleted file mode 100644 (file)
index 95099c1..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark fcntl getfl
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/dev/null"
-
-static char                    *optf = DEFF;
-static int                     fd = -1;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_optstr, "f:");
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-fcntl (default %s)]\n"
-           "notes: measures fcntl()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       if ((fd = open(optf, O_RDONLY)) == -1) {
-               perror("open");
-               exit(1);
-       }
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       int                     flags;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (fcntl(fd, F_GETFL, &flags) == -1)
-                       res->re_errors++;
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/fcntl_ndelay.c b/tools/tests/libMicro/fcntl_ndelay.c
deleted file mode 100644 (file)
index 3f55a18..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * measures  O_NDELAY on socket
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-static int                     fd = -1;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage,
-           "notes: measures F_GETFL/F_SETFL O_NDELAY on socket\n");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       fd = socket(AF_INET, SOCK_STREAM, 0);
-       if (fd == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       int                     flags;
-
-       for (i = 0; i < lm_optB; i += 4) {
-               if (fcntl(fd, F_GETFL, &flags) < 0)
-                       res->re_errors++;
-               flags |= O_NDELAY;
-
-               if (fcntl(fd, F_SETFL, &flags) < 0)
-                       res->re_errors++;
-
-               if (fcntl(fd, F_GETFL, &flags) < 0)
-                       res->re_errors++;
-               flags &= ~O_NDELAY;
-
-               if (fcntl(fd, F_SETFL, &flags) < 0)
-                       res->re_errors++;
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/file_lock.c b/tools/tests/libMicro/file_lock.c
deleted file mode 100644 (file)
index fc11964..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * test file locking
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-static int                     file;
-
-int
-block(int index)
-{
-       struct flock            fl;
-
-       fl.l_type = F_WRLCK;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = index;
-       fl.l_len = 1;
-       return (fcntl(file, F_SETLKW, &fl) == -1);
-}
-
-int
-unblock(int index)
-{
-       struct flock            fl;
-
-       fl.l_type = F_UNLCK;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = index;
-       fl.l_len = 1;
-       return (fcntl(file, F_SETLK, &fl) == -1);
-}
-int
-benchmark_init()
-{
-       char                    fname[80];
-       int     errors = 0;
-
-       (void) sprintf(fname, "/private/tmp/oneflock.%ld", getpid());
-
-       file = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600);
-
-       if (file == -1) {
-               errors++;
-       }
-       if (unlink(fname)) {
-               errors++;
-       }
-
-       lm_tsdsize = 0;
-
-       return (errors);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       int                     e = 0;
-
-       for (i = 0; i < lm_optB; i ++) {
-               e += block(0);
-               e += unblock(0);
-       }
-       res->re_count = i;
-       res->re_errors = e;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/fork.c b/tools/tests/libMicro/fork.c
deleted file mode 100644 (file)
index d033691..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark fork
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "libmicro.h"
-
-static barrier_t               *b;
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_pids;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-       (void) sprintf(lm_usage, "notes: measures fork()\n");
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       b = barrier_create(lm_optP * lm_optT * (lm_optB + 1), 0);
-
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       (void) barrier_destroy(b);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_pids = (int *)malloc(lm_optB * sizeof (pid_t));
-               if (ts->ts_pids == NULL) {
-                       errors++;
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_pids[i] = fork();
-               switch (ts->ts_pids[i]) {
-               case 0:
-                       (void) barrier_queue(b, NULL);
-                       exit(0);
-                       break;
-               case -1:
-                       res->re_errors++;
-                       break;
-               default:
-                       continue;
-               }
-       }
-       res->re_count = lm_optB;
-
-       (void) barrier_queue(b, NULL);
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (ts->ts_pids[i] > 0) {
-                       (void) waitpid(ts->ts_pids[i], NULL, 0);
-               }
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/getcontext.c b/tools/tests/libMicro/getcontext.c
deleted file mode 100644 (file)
index 524a016..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * getcontext
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ucontext.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures getcontext()\n");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               ucontext_t uc;
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-               (void) getcontext(&uc);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/getenv.c b/tools/tests/libMicro/getenv.c
deleted file mode 100644 (file)
index f75bfd4..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * test getenv
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-#define        DEFS                    100
-
-static int                     opts = DEFS;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_optstr, "s:");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-s search-size (default = %d)]\n"
-           "notes: measures time to search env for missing string\n",
-           DEFS);
-
-       lm_nsecs_per_op = 200;
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 's':
-               opts = atoi(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       extern char **          environ;
-       int                     i, j;
-
-       /* count environment strings */
-
-       for (i = 0; environ[i++]; )
-               ;
-
-       /*
-        * pad to desired count
-        */
-
-       if (opts < i)
-               opts = i;
-
-       for (j = i; j < opts; j++) {
-               char buf[80];
-               (void) sprintf(buf, "VAR_%d=%d", j, j);
-               (void) putenv(strdup(buf));
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       char                    *search = "RUMPLSTILTSKIN";
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-               (void) getenv(search);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/getpeername.c b/tools/tests/libMicro/getpeername.c
deleted file mode 100644 (file)
index 877215d..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * getpeername test
- */
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-#define        FIRSTPORT               12345
-
-static int                     sock = -1;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures getpeername()\n");
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     j;
-       int                     opt = 1;
-       int                     result;
-       socklen_t               size;
-       struct hostent  *host;
-       struct sockaddr_in      adds;
-       int                     sock2, sock3;
-
-       sock2 = socket(AF_INET, SOCK_STREAM, 0);
-       if (sock2 == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       if (setsockopt(sock2, SOL_SOCKET, SO_REUSEADDR,
-           &opt, sizeof (int)) == -1) {
-               perror("setsockopt");
-               exit(1);
-       }
-
-       if ((host = gethostbyname("localhost")) == NULL) {
-               perror("gethostbyname");
-               exit(1);
-       }
-
-       j = FIRSTPORT;
-       for (;;) {
-               (void) memset(&adds, 0, sizeof (struct sockaddr_in));
-               adds.sin_family = AF_INET;
-               adds.sin_port = htons(j++);
-               (void) memcpy(&adds.sin_addr.s_addr, host->h_addr_list[0],
-                   sizeof (struct in_addr));
-
-               if (bind(sock2, (struct sockaddr *)&adds,
-                   sizeof (struct sockaddr_in)) == 0) {
-                       break;
-               }
-
-               if (errno != EADDRINUSE) {
-                       perror("bind");
-                       exit(1);
-               }
-       }
-
-       if (listen(sock2, 5) == -1) {
-               perror("listen");
-               exit(1);
-       }
-
-       sock3 = socket(AF_INET, SOCK_STREAM, 0);
-       if (sock3 == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       if (fcntl(sock3, F_SETFL, O_NDELAY) == -1) {
-               perror("fcntl");
-               exit(1);
-       }
-
-       result = connect(sock3, (struct sockaddr *)&adds,
-           sizeof (struct sockaddr_in));
-       if ((result == -1) && (errno != EINPROGRESS)) {
-               perror("connect");
-               exit(1);
-       }
-
-       size = sizeof (struct sockaddr);
-       sock = accept(sock2, (struct sockaddr *)&adds, &size);
-       if (sock == -1) {
-               perror("accept");
-               exit(1);
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct sockaddr_in      adds;
-       socklen_t               size;
-
-       for (i = 0; i < lm_optB; i++) {
-               size = sizeof (struct sockaddr_in);
-               if (getpeername(sock, (struct sockaddr *)&adds, &size) == -1) {
-                       perror("getpeername");
-                       exit(1);
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/getpid.c b/tools/tests/libMicro/getpid.c
deleted file mode 100644 (file)
index 4ac8165..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * getpid
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures getpid()");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i ++) {
-               (void) getpid();
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/getrusage.c b/tools/tests/libMicro/getrusage.c
deleted file mode 100644 (file)
index 2f02213..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * getrusage
- */
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/resource.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures getrusage(RUSAGE_SELF)\n");
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct rusage           u;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-               (void) getrusage(RUSAGE_SELF, &u);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/getsockname.c b/tools/tests/libMicro/getsockname.c
deleted file mode 100644 (file)
index e3f7769..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * getsockname
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-#define        FIRSTPORT               12345
-
-static struct sockaddr_in      adds;
-static int                     sock = -1;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures getsockname()()\n");
-       lm_tsdsize = 0;
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     j;
-       int                     opt = 1;
-       struct hostent  *host;
-
-       sock = socket(AF_INET, SOCK_STREAM, 0);
-       if (sock == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-           &opt, sizeof (int)) == -1) {
-               perror("setsockopt");
-               exit(1);
-       }
-
-       if ((host = gethostbyname("localhost")) == NULL) {
-               perror("gethostbyname");
-               exit(1);
-       }
-
-       j = FIRSTPORT;
-       for (;;) {
-               (void) memset(&adds, 0, sizeof (struct sockaddr_in));
-               adds.sin_family = AF_INET;
-               adds.sin_port = htons(j++);
-               (void) memcpy(&adds.sin_addr.s_addr, host->h_addr_list[0],
-                   sizeof (struct in_addr));
-
-               if (bind(sock, (struct sockaddr *)&adds,
-                   sizeof (struct sockaddr_in)) == 0) {
-                       break;
-               }
-
-               if (errno != EADDRINUSE) {
-                       perror("bind");
-                       exit(1);
-               }
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct sockaddr_in      adds;
-       socklen_t               size;
-
-       for (i = 0; i < lm_optB; i++) {
-               size = sizeof (struct sockaddr_in);
-               if (getsockname(sock, (struct sockaddr *)&adds, &size) == -1)
-                       res->re_errors++;
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/gettimeofday.c b/tools/tests/libMicro/gettimeofday.c
deleted file mode 100644 (file)
index a17bf75..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * gettimeofday test
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures gettimeofday()");
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct timeval t;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-               (void) gettimeofday(&t, NULL);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/isatty.c b/tools/tests/libMicro/isatty.c
deleted file mode 100644 (file)
index 68aaf85..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * isatty test
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/dev/tty"
-static char                    *optf = DEFF;
-static int                     optb = 0;
-
-typedef struct {
-       int                     ts_fd;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:b");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-isatty (default %s)]\n"
-           "       [-b] (try to isatty an unopened fd)\n"
-           "notes: measures isatty()",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       case 'b':
-               optb = 1;
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       ts->ts_fd = ((optb == 0) ?
-           open(optf, O_RDONLY) : 1024);
-       if (ts->ts_fd == -1) {
-               return (1);
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (isatty(ts->ts_fd) == -1) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/libmicro.c b/tools/tests/libMicro/libmicro.c
deleted file mode 100644 (file)
index a3239c6..0000000
+++ /dev/null
@@ -1,1608 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmarking routines
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <ctype.h>
-#include <string.h>
-#include <strings.h>
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <poll.h>
-#include <pthread.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <sys/resource.h>
-#include <math.h>
-#include <limits.h>
-
-#ifdef __sun
-#include <sys/elf.h>
-#endif
-
-#include "libmicro.h"
-
-
-#if defined(__APPLE__)
-#include <mach/mach_time.h>
-
-long long
-gethrtime(void)
-{
-   long long        elapsed;
-   static long long        start;
-   static mach_timebase_info_data_t    sTimebaseInfo = { 0, 0 };
-
-   // If this is the first time we've run, get the timebase.
-   // We can use denom == 0 to indicate that sTimebaseInfo is
-   // uninitialised because it makes no sense to have a zero
-   // denominator in a fraction.
-
-   if ( sTimebaseInfo.denom == 0 ) {
-       (void) mach_timebase_info(&sTimebaseInfo);
-               start = mach_absolute_time();
-   }
-
-   elapsed = mach_absolute_time() - start;
-
-   // Convert to nanoseconds.
-       // return (elapsed * (long long)sTimebaseInfo.numer)/(long long)sTimebaseInfo.denom;
-       
-       // Provided the final result is representable in 64 bits the following maneuver will
-       // deliver that result without intermediate overflow.
-       if (sTimebaseInfo.denom == sTimebaseInfo.numer)
-               return elapsed;
-       else if (sTimebaseInfo.denom == 1)
-               return elapsed * (long long)sTimebaseInfo.numer;
-       else {
-       // Decompose elapsed = eta32 * 2^32 + eps32:
-       long long eta32 = elapsed >> 32;
-       long long eps32 = elapsed & 0x00000000ffffffffLL;
-
-       long long numer = sTimebaseInfo.numer, denom = sTimebaseInfo.denom;
-
-       // Form product of elapsed64 (decomposed) and numer:
-       long long mu64 = numer * eta32;
-       long long lambda64 = numer * eps32;
-
-       // Divide the constituents by denom:
-       long long q32 = mu64/denom;
-       long long r32 = mu64 - (q32 * denom); // mu64 % denom
-
-       return (q32 << 32) + ((r32 << 32) + lambda64)/denom;
-       }
-}
-
-#endif
-
-/*
- * user visible globals
- */
-
-int                            lm_argc = 0;
-char **                                lm_argv = NULL;
-
-int                            lm_opt1;
-int                            lm_optA;
-int                            lm_optB;
-int                            lm_optC = 100;
-int                            lm_optD;
-int                            lm_optE;
-int                            lm_optH;
-int                            lm_optI;
-int                            lm_optL = 0;
-int                            lm_optM = 0;
-char                           *lm_optN;
-int                            lm_optP;
-int                            lm_optS;
-int                            lm_optT;
-int                            lm_optW;
-
-int                            lm_def1 = 0;
-int                            lm_defB = 0; /* use lm_nsecs_per_op */
-int                            lm_defD = 10;
-int                            lm_defH = 0;
-char                           *lm_defN = NULL;
-int                            lm_defP = 1;
-
-int                            lm_defS = 0;
-int                            lm_defT = 1;
-
-/*
- * default on fast platform, should be overridden by individual
- * benchmarks if significantly wrong in either direction.
- */
-
-int                            lm_nsecs_per_op = 5;
-
-char                           *lm_procpath;
-char                           lm_procname[STRSIZE];
-char                           lm_usage[STRSIZE];
-char                           lm_optstr[STRSIZE];
-char                           lm_header[STRSIZE];
-size_t                         lm_tsdsize = 0;
-
-
-/*
- *  Globals we do not export to the user
- */
-
-static barrier_t               *lm_barrier;
-static pid_t                   *pids = NULL;
-static pthread_t               *tids = NULL;
-static int                     pindex = -1;
-static void                    *tsdseg = NULL;
-static size_t                  tsdsize = 0;
-
-#ifdef USE_RDTSC
-static long long               lm_hz = 0;
-#endif
-
-
-/*
- * Forward references
- */
-
-static void            worker_process();
-static void            usage();
-static void            print_stats(barrier_t *);
-static void            print_histo(barrier_t *);
-static int             remove_outliers(double *, int, stats_t *);
-static long long       nsecs_overhead;
-static long long       nsecs_resolution;
-static long long       get_nsecs_overhead();
-static int             crunch_stats(double *, int, stats_t *);
-static void            compute_stats(barrier_t *);
-/*
- * main routine; renamed in this file to allow linking with other
- * files
- */
-
-int
-actual_main(int argc, char *argv[])
-{
-       int                     i;
-       int                     opt;
-       extern char             *optarg;
-       char                    *tmp;
-       char                    optstr[256];
-       barrier_t               *b;
-       long long               startnsecs = getnsecs();
-
-#ifdef USE_RDTSC
-       if (getenv("LIBMICRO_HZ") == NULL) {
-               (void) printf("LIBMICRO_HZ needed but not set\n");
-               exit(1);
-       }
-       lm_hz = strtoll(getenv("LIBMICRO_HZ"), NULL, 10);
-#endif
-
-       lm_argc = argc;
-       lm_argv = argv;
-
-       /* before we do anything */
-       (void) benchmark_init();
-
-
-       nsecs_overhead = get_nsecs_overhead();
-       nsecs_resolution = get_nsecs_resolution();
-
-       /*
-        * Set defaults
-        */
-
-       lm_opt1 = lm_def1;
-       lm_optB = lm_defB;
-       lm_optD = lm_defD;
-       lm_optH = lm_defH;
-       lm_optN = lm_defN;
-       lm_optP = lm_defP;
-
-       lm_optS = lm_defS;
-       lm_optT = lm_defT;
-
-       /*
-        * squirrel away the path to the current
-        * binary in a way that works on both
-        * Linux and Solaris
-        */
-
-       if (*argv[0] == '/') {
-               lm_procpath = strdup(argv[0]);
-               *strrchr(lm_procpath, '/') = 0;
-       } else {
-               char path[1024];
-               (void) getcwd(path, 1024);
-               (void) strcat(path, "/");
-               (void) strcat(path, argv[0]);
-               *strrchr(path, '/') = 0;
-               lm_procpath = strdup(path);
-       }
-
-       /*
-        * name of binary
-        */
-
-       if ((tmp = strrchr(argv[0], '/')) == NULL)
-               (void) strcpy(lm_procname, argv[0]);
-       else
-               (void) strcpy(lm_procname, tmp + 1);
-
-       if (lm_optN == NULL) {
-               lm_optN = lm_procname;
-       }
-
-       /*
-        * Parse command line arguments
-        */
-
-       (void) sprintf(optstr, "1AB:C:D:EHI:LMN:P:RST:VW?%s", lm_optstr);
-       while ((opt = getopt(argc, argv, optstr)) != -1) {
-               switch (opt) {
-               case '1':
-                       lm_opt1 = 1;
-                       break;
-               case 'A':
-                       lm_optA = 1;
-                       break;
-               case 'B':
-                       lm_optB = sizetoint(optarg);
-                       break;
-               case 'C':
-                       lm_optC = sizetoint(optarg);
-                       break;
-               case 'D':
-                       lm_optD = sizetoint(optarg);
-                       break;
-               case 'E':
-                       lm_optE = 1;
-                       break;
-               case 'H':
-                       lm_optH = 1;
-                       break;
-               case 'I':
-                       lm_optI = sizetoint(optarg);
-                       break;
-               case 'L':
-                       lm_optL = 1;
-                       break;
-               case 'M':
-                       lm_optM = 1;
-                       break;
-               case 'N':
-                       lm_optN = optarg;
-                       break;
-               case 'P':
-                       lm_optP = sizetoint(optarg);
-                       break;
-               case 'S':
-                       lm_optS = 1;
-                       break;
-               case 'T':
-                       lm_optT = sizetoint(optarg);
-                       break;
-               case 'V':
-                       (void) printf("%s\n", LIBMICRO_VERSION);
-                       exit(0);
-                       break;
-               case 'W':
-                       lm_optW = 1;
-                       lm_optS = 1;
-                       break;
-               case '?':
-                       usage();
-                       exit(0);
-                       break;
-               default:
-                       if (benchmark_optswitch(opt, optarg) == -1) {
-                               usage();
-                               exit(0);
-                       }
-               }
-       }
-
-       /* deal with implicit and overriding options */
-       if (lm_opt1 && lm_optP > 1) {
-               lm_optP = 1;
-               (void) printf("warning: -1 overrides -P\n");
-       }
-
-       if (lm_optE) {
-               (void) fprintf(stderr, "Running:%20s", lm_optN);
-               (void) fflush(stderr);
-       }
-
-       if (lm_optB == 0) {
-               /*
-                * neither benchmark or user has specified the number
-                * of cnts/sample, so use computed value
-                */
-               if (lm_optI)
-                       lm_nsecs_per_op = lm_optI;
-#define BLOCK_TOCK_DURATION 10000 /* number of raw timer "tocks" ideally comprising a block of work */
-               lm_optB = nsecs_resolution * BLOCK_TOCK_DURATION / lm_nsecs_per_op;
-               if (lm_optB == 0)
-                       lm_optB = 1;
-       }
-
-       /*
-        * now that the options are set
-        */
-
-       if (benchmark_initrun() == -1) {
-               exit(1);
-       }
-
-       /* allocate dynamic data */
-       pids = (pid_t *)malloc(lm_optP * sizeof (pid_t));
-       if (pids == NULL) {
-               perror("malloc(pids)");
-               exit(1);
-       }
-       tids = (pthread_t *)malloc(lm_optT * sizeof (pthread_t));
-       if (tids == NULL) {
-               perror("malloc(tids)");
-               exit(1);
-       }
-
-       /* check that the case defines lm_tsdsize before proceeding */
-       if (lm_tsdsize == (size_t)-1) {
-               (void) fprintf(stderr, "error in benchmark_init: "
-                   "lm_tsdsize not set\n");
-               exit(1);
-       }
-
-       /* round up tsdsize to nearest 128 to eliminate false sharing */
-       tsdsize = ((lm_tsdsize + 127) / 128) * 128;
-
-       /* allocate sufficient TSD for each thread in each process */
-       tsdseg = (void *)mmap(NULL, lm_optT * lm_optP * tsdsize + 8192,
-           PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0L);
-       if (tsdseg == NULL) {
-               perror("mmap(tsd)");
-               exit(1);
-       }
-
-       /* initialise worker synchronisation */
-       b = barrier_create(lm_optT * lm_optP, DATASIZE);
-       if (b == NULL) {
-               perror("barrier_create()");
-               exit(1);
-       }
-       lm_barrier = b;
-       b->ba_flag = 1;
-
-       /* need this here so that parent and children can call exit() */
-       (void) fflush(stdout);
-       (void) fflush(stderr);
-
-       /* when we started and when to stop */
-
-       b->ba_starttime = getnsecs();
-       b->ba_deadline = (long long) (b->ba_starttime + (lm_optD * 1000000LL));
-
-       /* do the work */
-       if (lm_opt1) {
-               /* single process, non-fork mode */
-               pindex = 0;
-               worker_process();
-       } else {
-               /* create worker processes */
-               for (i = 0; i < lm_optP; i++) {
-                       pids[i] = fork();
-
-                       switch (pids[i]) {
-                       case 0:
-                               pindex = i;
-                               worker_process();
-                               exit(0);
-                               break;
-                       case -1:
-                               perror("fork");
-                               exit(1);
-                               break;
-                       default:
-                               continue;
-                       }
-               }
-
-               /* wait for worker processes */
-               for (i = 0; i < lm_optP; i++) {
-                       if (pids[i] > 0) {
-                               (void) waitpid(pids[i], NULL, 0);
-                       }
-               }
-       }
-
-       b->ba_endtime = getnsecs();
-
-       /* compute results */
-
-       compute_stats(b);
-
-       /* print arguments benchmark was invoked with ? */
-       if (lm_optL) {
-               int l;
-               (void) printf("# %s ", argv[0]);
-               for (l = 1; l < argc; l++) {
-                       (void) printf("%s ", argv[l]);
-               }
-               (void) printf("\n");
-       }
-
-       /* print result header (unless suppressed) */
-       if (!lm_optH) {
-               (void) printf("%12s %3s %3s %12s %12s %8s %8s %s\n",
-                   "", "prc", "thr",
-                   "usecs/call",
-                   "samples", "errors", "cnt/samp", lm_header);
-       }
-
-       /* print result */
-
-       (void) printf("%-12s %3d %3d %12.5f %12d %8lld %8d %s\n",
-           lm_optN, lm_optP, lm_optT,
-           (lm_optM?b->ba_corrected.st_mean:b->ba_corrected.st_median),
-           b->ba_batches, b->ba_errors, lm_optB,
-           benchmark_result());
-
-       if (lm_optS) {
-               print_stats(b);
-       }
-
-       /* just incase something goes awry */
-       (void) fflush(stdout);
-       (void) fflush(stderr);
-
-       /* cleanup by stages */
-       (void) benchmark_finirun();
-       (void) barrier_destroy(b);
-       (void) benchmark_fini();
-
-       if (lm_optE) {
-               (void) fprintf(stderr, " for %12.5f seconds\n",
-                   (double)(getnsecs() - startnsecs) /
-                   1.e9);
-               (void) fflush(stderr);
-       }
-       return (0);
-}
-
-void *
-worker_thread(void *arg)
-{
-       result_t                r;
-       long long               last_sleep = 0;
-       long long               t;
-
-       r.re_errors = benchmark_initworker(arg);
-
-       while (lm_barrier->ba_flag) {
-               r.re_count = 0;
-               r.re_errors += benchmark_initbatch(arg);
-
-               /* sync to clock */
-
-               if (lm_optA && ((t = getnsecs()) - last_sleep) > 75000000LL) {
-                       (void) poll(0, 0, 10);
-                       last_sleep = t;
-               }
-               /* wait for it ... */
-               (void) barrier_queue(lm_barrier, NULL);
-
-               /* time the test */
-               r.re_t0 = getnsecs();
-               (void) benchmark(arg, &r);
-               r.re_t1 = getnsecs();
-
-               /* time to stop? */
-               if (r.re_t1 > lm_barrier->ba_deadline &&
-                   (!lm_optC || lm_optC < lm_barrier->ba_batches)) {
-                       lm_barrier->ba_flag = 0;
-               }
-
-               /* record results and sync */
-               (void) barrier_queue(lm_barrier, &r);
-
-               (void) benchmark_finibatch(arg);
-
-               r.re_errors = 0;
-       }
-
-       (void) benchmark_finiworker(arg);
-
-       return (0);
-}
-
-void
-worker_process()
-{
-       int                     i;
-       void                    *tsd;
-
-       for (i = 1; i < lm_optT; i++) {
-               tsd = gettsd(pindex, i);
-               if (pthread_create(&tids[i], NULL, worker_thread, tsd) != 0) {
-                       perror("pthread_create");
-                       exit(1);
-               }
-       }
-
-       tsd = gettsd(pindex, 0);
-       (void) worker_thread(tsd);
-
-       for (i = 1; i < lm_optT; i++) {
-               (void) pthread_join(tids[i], NULL);
-       }
-}
-
-void
-usage()
-{
-       (void) printf(
-           "usage: %s\n"
-           "       [-1] (single process; overrides -P > 1)\n"
-           "       [-A] (align with clock)\n"
-           "       [-B batch-size (default %d)]\n"
-           "       [-C minimum number of samples (default 0)]\n"
-           "       [-D duration in msecs (default %ds)]\n"
-           "       [-E (echo name to stderr)]\n"
-           "       [-H] (suppress headers)\n"
-           "       [-I] nsecs per op (used to compute batch size)"
-           "       [-L] (print argument line)\n"
-           "       [-M] (reports mean rather than median)\n"
-           "       [-N test-name (default '%s')]\n"
-           "       [-P processes (default %d)]\n"
-           "       [-S] (print detailed stats)\n"
-           "       [-T threads (default %d)]\n"
-           "       [-V] (print the libMicro version and exit)\n"
-           "       [-W] (flag possible benchmark problems)\n"
-           "%s\n",
-           lm_procname,
-           lm_defB, lm_defD, lm_procname, lm_defP, lm_defT,
-           lm_usage);
-}
-
-void
-print_warnings(barrier_t *b)
-{
-       int head = 0;
-       int increase;
-
-       if (b->ba_quant) {
-               if (!head++) {
-                       (void) printf("#\n# WARNINGS\n");
-               }
-               increase = (int)(floor((nsecs_resolution * 100.0) /
-                   ((double)lm_optB * b->ba_corrected.st_median * 1000.0)) +
-                   1.0);
-               (void) printf("#     Quantization error likely;"
-                   "increase batch size (-B option) %dX to avoid.\n",
-                   increase);
-       }
-
-       /*
-        * XXX should warn on median != mean by a lot
-        */
-
-       if (b->ba_errors) {
-               if (!head++) {
-                       (void) printf("#\n# WARNINGS\n");
-               }
-               (void) printf("#     Errors occured during benchmark.\n");
-       }
-}
-
-void
-print_stats(barrier_t *b)
-{
-       (void) printf("#\n");
-       (void) printf("# STATISTICS         %12s          %12s\n",
-           "usecs/call (raw)",
-           "usecs/call (outliers removed)");
-
-       if (b->ba_count == 0) {
-               (void) printf("zero samples\n");
-               return;
-       }
-
-       (void) printf("#                    min %12.5f            %12.5f\n",
-           b->ba_raw.st_min,
-           b->ba_corrected.st_min);
-
-       (void) printf("#                    max %12.5f            %12.5f\n",
-           b->ba_raw.st_max,
-           b->ba_corrected.st_max);
-       (void) printf("#                   mean %12.5f            %12.5f\n",
-           b->ba_raw.st_mean,
-           b->ba_corrected.st_mean);
-       (void) printf("#                 median %12.5f            %12.5f\n",
-           b->ba_raw.st_median,
-           b->ba_corrected.st_median);
-       (void) printf("#                 stddev %12.5f            %12.5f\n",
-           b->ba_raw.st_stddev,
-           b->ba_corrected.st_stddev);
-       (void) printf("#         standard error %12.5f            %12.5f\n",
-           b->ba_raw.st_stderr,
-           b->ba_corrected.st_stderr);
-       (void) printf("#   99%% confidence level %12.5f            %12.5f\n",
-           b->ba_raw.st_99confidence,
-           b->ba_corrected.st_99confidence);
-       (void) printf("#                   skew %12.5f            %12.5f\n",
-           b->ba_raw.st_skew,
-           b->ba_corrected.st_skew);
-       (void) printf("#               kurtosis %12.5f            %12.5f\n",
-           b->ba_raw.st_kurtosis,
-           b->ba_corrected.st_kurtosis);
-
-       (void) printf("#       time correlation %12.5f            %12.5f\n",
-           b->ba_raw.st_timecorr,
-           b->ba_corrected.st_timecorr);
-       (void) printf("#\n");
-
-       (void) printf("#           elasped time %12.5f\n", (b->ba_endtime -
-           b->ba_starttime) / 1.0e9);
-       (void) printf("#      number of samples %12d\n",   b->ba_batches);
-       (void) printf("#     number of outliers %12d\n", b->ba_outliers);
-       (void) printf("#      getnsecs overhead %12d\n", (int)nsecs_overhead);
-
-       (void) printf("#\n");
-       (void) printf("# DISTRIBUTION\n");
-
-       print_histo(b);
-
-       if (lm_optW) {
-               print_warnings(b);
-       }
-}
-
-void
-update_stats(barrier_t *b, result_t *r)
-{
-       double                  time;
-       double                  nsecs_per_call;
-
-       if (b->ba_waiters == 0) {
-               /* first thread only */
-               b->ba_t0 = r->re_t0;
-               b->ba_t1 = r->re_t1;
-               b->ba_count0 = 0;
-               b->ba_errors0 = 0;
-       } else {
-               /* all but first thread */
-               if (r->re_t0 < b->ba_t0) {
-                       b->ba_t0 = r->re_t0;
-               }
-               if (r->re_t1 > b->ba_t1) {
-                       b->ba_t1 = r->re_t1;
-               }
-       }
-
-       b->ba_count0  += r->re_count;
-       b->ba_errors0 += r->re_errors;
-
-       if (b->ba_waiters == b->ba_hwm - 1) {
-               /* last thread only */
-
-
-               time = (double)b->ba_t1 - (double)b->ba_t0 -
-                   (double)nsecs_overhead;
-
-               if (time < 100 * nsecs_resolution)
-                       b->ba_quant++;
-
-               /*
-                * normalize by procs * threads if not -U
-                */
-
-               nsecs_per_call = time / (double)b->ba_count0 *
-                   (double)(lm_optT * lm_optP);
-
-               b->ba_count  += b->ba_count0;
-               b->ba_errors += b->ba_errors0;
-
-               b->ba_data[b->ba_batches % b->ba_datasize] =
-                   nsecs_per_call;
-
-               b->ba_batches++;
-       }
-}
-
-#ifdef USE_SEMOP
-barrier_t *
-barrier_create(int hwm, int datasize)
-{
-       struct sembuf           s[1];
-       barrier_t               *b;
-
-       /*LINTED*/
-       b = (barrier_t *)mmap(NULL,
-           sizeof (barrier_t) + (datasize - 1) * sizeof (double),
-           PROT_READ | PROT_WRITE,
-           MAP_SHARED | MAP_ANON, -1, 0L);
-       if (b == (barrier_t *)MAP_FAILED) {
-               return (NULL);
-       }
-       b->ba_datasize = datasize;
-
-       b->ba_flag  = 0;
-       b->ba_hwm   = hwm;
-       b->ba_semid = semget(IPC_PRIVATE, 3, 0600);
-       if (b->ba_semid == -1) {
-               (void) munmap((void *)b, sizeof (barrier_t));
-               return (NULL);
-       }
-
-       /* [hwm - 1, 0, 0] */
-       s[0].sem_num = 0;
-       s[0].sem_op  = hwm - 1;
-       s[0].sem_flg = 0;
-       if (semop(b->ba_semid, s, 1) == -1) {
-               perror("semop(1)");
-               (void) semctl(b->ba_semid, 0, IPC_RMID);
-               (void) munmap((void *)b, sizeof (barrier_t));
-               return (NULL);
-       }
-
-       b->ba_waiters = 0;
-       b->ba_phase = 0;
-
-       b->ba_count = 0;
-       b->ba_errors = 0;
-
-       return (b);
-}
-
-int
-barrier_destroy(barrier_t *b)
-{
-       (void) semctl(b->ba_semid, 0, IPC_RMID);
-       (void) munmap((void *)b, sizeof (barrier_t));
-
-       return (0);
-}
-
-int
-barrier_queue(barrier_t *b, result_t *r)
-{
-       struct sembuf           s[2];
-
-       /*
-        * {s0(-(hwm-1))}
-        * if ! nowait {s1(-(hwm-1))}
-        *   (all other threads)
-        *   update shared stats
-        *   {s0(hwm-1), s1(1)}
-        *   {s0(1), s2(-1)}
-        * else
-        *   (last thread)
-        *   update shared stats
-        *   {s2(hwm-1)}
-        */
-
-       s[0].sem_num = 0;
-       s[0].sem_op  = -(b->ba_hwm - 1);
-       s[0].sem_flg = 0;
-       if (semop(b->ba_semid, s, 1) == -1) {
-               perror("semop(2)");
-               return (-1);
-       }
-
-       s[0].sem_num = 1;
-       s[0].sem_op  = -(b->ba_hwm - 1);
-       s[0].sem_flg = IPC_NOWAIT;
-       if (semop(b->ba_semid, s, 1) == -1) {
-               if (errno != EAGAIN) {
-                       perror("semop(3)");
-                       return (-1);
-               }
-
-               /* all but the last thread */
-
-               if (r != NULL) {
-                       update_stats(b, r);
-               }
-
-               b->ba_waiters++;
-
-               s[0].sem_num = 0;
-               s[0].sem_op  = b->ba_hwm - 1;
-               s[0].sem_flg = 0;
-               s[1].sem_num = 1;
-               s[1].sem_op  = 1;
-               s[1].sem_flg = 0;
-               if (semop(b->ba_semid, s, 2) == -1) {
-                       perror("semop(4)");
-                       return (-1);
-               }
-
-               s[0].sem_num = 0;
-               s[0].sem_op  = 1;
-               s[0].sem_flg = 0;
-               s[1].sem_num = 2;
-               s[1].sem_op  = -1;
-               s[1].sem_flg = 0;
-               if (semop(b->ba_semid, s, 2) == -1) {
-                       perror("semop(5)");
-                       return (-1);
-               }
-
-       } else {
-               /* the last thread */
-
-               if (r != NULL) {
-                       update_stats(b, r);
-               }
-
-               b->ba_waiters = 0;
-               b->ba_phase++;
-
-               s[0].sem_num = 2;
-               s[0].sem_op  = b->ba_hwm - 1;
-               s[0].sem_flg = 0;
-               if (semop(b->ba_semid, s, 1) == -1) {
-                       perror("semop(6)");
-                       return (-1);
-               }
-       }
-
-       return (0);
-}
-
-#else /* USE_SEMOP */
-
-barrier_t *
-barrier_create(int hwm, int datasize)
-{
-       pthread_mutexattr_t     attr;
-       pthread_condattr_t      cattr;
-       barrier_t               *b;
-
-       /*LINTED*/
-       b = (barrier_t *)mmap(NULL,
-           sizeof (barrier_t) + (datasize - 1) * sizeof (double),
-           PROT_READ | PROT_WRITE,
-           MAP_SHARED | MAP_ANON, -1, 0L);
-       if (b == (barrier_t *)MAP_FAILED) {
-               return (NULL);
-       }
-       b->ba_datasize = datasize;
-
-       b->ba_hwm = hwm;
-       b->ba_flag  = 0;
-
-       (void) pthread_mutexattr_init(&attr);
-       (void) pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
-
-       (void) pthread_condattr_init(&cattr);
-       (void) pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
-
-       (void) pthread_mutex_init(&b->ba_lock, &attr);
-       (void) pthread_cond_init(&b->ba_cv, &cattr);
-
-       b->ba_waiters = 0;
-       b->ba_phase = 0;
-
-       b->ba_count = 0;
-       b->ba_errors = 0;
-
-       return (b);
-}
-
-int
-barrier_destroy(barrier_t *b)
-{
-       (void) munmap((void *)b, sizeof (barrier_t));
-
-       return (0);
-}
-
-int
-barrier_queue(barrier_t *b, result_t *r)
-{
-       int                     phase;
-
-       (void) pthread_mutex_lock(&b->ba_lock);
-
-       if (r != NULL) {
-               update_stats(b, r);
-       }
-
-       phase = b->ba_phase;
-
-       b->ba_waiters++;
-       if (b->ba_hwm == b->ba_waiters) {
-               b->ba_waiters = 0;
-               b->ba_phase++;
-               (void) pthread_cond_broadcast(&b->ba_cv);
-       }
-
-       while (b->ba_phase == phase) {
-               (void) pthread_cond_wait(&b->ba_cv, &b->ba_lock);
-       }
-
-       (void) pthread_mutex_unlock(&b->ba_lock);
-       return (0);
-}
-#endif /* USE_SEMOP */
-
-int
-gettindex()
-{
-       int                     i;
-
-       if (tids == NULL) {
-               return (-1);
-       }
-
-       for (i = 1; i < lm_optT; i++) {
-               if (pthread_self() == tids[i]) {
-                       return (i);
-               }
-       }
-
-       return (0);
-}
-
-int
-getpindex()
-{
-       return (pindex);
-}
-
-void *
-gettsd(int p, int t)
-{
-       if ((p < 0) || (p >= lm_optP) || (t < 0) || (t >= lm_optT))
-               return (NULL);
-
-       return ((void *)((unsigned long)tsdseg +
-           (((p * lm_optT) + t) * tsdsize)));
-}
-
-#if defined(__APPLE__)
-int
-gettsdindex(void *arg){
-        /*
-         * gettindex() can race with pthread_create() filling in tids[].
-         * This is an alternative approach to finding the calling thread's tsd in t
-sdseg
-         */
-        return tsdsize ? ((unsigned long)arg - (unsigned long)tsdseg)/tsdsize : 0;
-}
-#endif /* __APPLE__ */
-
-#ifdef USE_GETHRTIME
-long long
-getnsecs()
-{
-       return (gethrtime());
-}
-
-long long
-getusecs()
-{
-       return (gethrtime() / 1000);
-}
-
-#elif USE_RDTSC /* USE_GETHRTIME */
-
-__inline__ long long
-rdtsc(void)
-{
-       unsigned long long x;
-       __asm__ volatile(".byte 0x0f, 0x31" : "=A" (x));
-       return (x);
-}
-
-long long
-getusecs()
-{
-       return (rdtsc() * 1000000 / lm_hz);
-}
-
-long long
-getnsecs()
-{
-       return (rdtsc() * 1000000000 / lm_hz);
-}
-
-#else /* USE_GETHRTIME */
-
-long long
-getusecs()
-{
-       struct timeval          tv;
-
-       (void) gettimeofday(&tv, NULL);
-
-       return ((long long)tv.tv_sec * 1000000LL + (long long) tv.tv_usec);
-}
-
-long long
-getnsecs()
-{
-       struct timeval          tv;
-
-       (void) gettimeofday(&tv, NULL);
-
-       return ((long long)tv.tv_sec * 1000000000LL +
-           (long long) tv.tv_usec * 1000LL);
-}
-
-#endif /* USE_GETHRTIME */
-
-int
-setfdlimit(int limit)
-{
-       struct rlimit rlimit;
-
-       if (getrlimit(RLIMIT_NOFILE, &rlimit) < 0) {
-               perror("getrlimit");
-               exit(1);
-       }
-
-       if (rlimit.rlim_cur > limit)
-               return (0); /* no worries */
-
-       rlimit.rlim_cur = limit;
-
-       if (rlimit.rlim_max < limit)
-               rlimit.rlim_max = limit;
-
-       if (setrlimit(RLIMIT_NOFILE, &rlimit) < 0) {
-               perror("setrlimit");
-               exit(3);
-       }
-
-       return (0);
-}
-
-
-#define        KILOBYTE                1024
-#define        MEGABYTE                (KILOBYTE * KILOBYTE)
-#define        GIGABYTE                (KILOBYTE * MEGABYTE)
-
-long long
-sizetoll(const char *arg)
-{
-       int                     len = strlen(arg);
-       int                     i;
-       long long               mult = 1;
-
-       if (len && isalpha(arg[len - 1])) {
-               switch (arg[len - 1]) {
-
-               case 'k':
-               case 'K':
-                       mult = KILOBYTE;
-                       break;
-               case 'm':
-               case 'M':
-                       mult = MEGABYTE;
-                       break;
-               case 'g':
-               case 'G':
-                       mult = GIGABYTE;
-                       break;
-               default:
-                       return (-1);
-               }
-
-               for (i = 0; i < len - 1; i++)
-                       if (!isdigit(arg[i]))
-                               return (-1);
-       }
-
-       return (mult * strtoll(arg, NULL, 10));
-}
-
-int
-sizetoint(const char *arg)
-{
-       int                     len = strlen(arg);
-       int                     i;
-       long long               mult = 1;
-
-       if (len && isalpha(arg[len - 1])) {
-               switch (arg[len - 1]) {
-
-               case 'k':
-               case 'K':
-                       mult = KILOBYTE;
-                       break;
-               case 'm':
-               case 'M':
-                       mult = MEGABYTE;
-                       break;
-               case 'g':
-               case 'G':
-                       mult = GIGABYTE;
-                       break;
-               default:
-                       return (-1);
-               }
-
-               for (i = 0; i < len - 1; i++)
-                       if (!isdigit(arg[i]))
-                               return (-1);
-       }
-
-       return (mult * atoi(arg));
-}
-
-static void
-print_bar(long count, long total)
-{
-       int                     i;
-
-       (void) putchar_unlocked(count ? '*' : ' ');
-       for (i = 1; i < (32 * count) / total; i++)
-               (void) putchar_unlocked('*');
-       for (; i < 32; i++)
-               (void) putchar_unlocked(' ');
-}
-
-static int
-doublecmp(const void *p1, const void *p2)
-{
-       double a = *((double *)p1);
-       double b = *((double *)p2);
-
-       if (a > b)
-               return (1);
-       if (a < b)
-               return (-1);
-       return (0);
-}
-
-static void
-print_histo(barrier_t *b)
-{
-       int                     n;
-       int                     i;
-       int                     j;
-       int                     last;
-       long long               maxcount;
-       double                  sum;
-       long long               min;
-       long long               scale;
-       double                  x;
-       long long               y;
-       long long               count;
-       int                     i95;
-       double                  p95;
-       double                  r95;
-       double                  m95;
-       histo_t                 *histo;
-
-       (void) printf("#        %12s %12s %32s %12s\n", "counts", "usecs/call",
-           "", "means");
-
-       /* calculate how much data we've captured */
-       n = b->ba_batches > b->ba_datasize ? b->ba_datasize : b->ba_batches;
-
-       /* find the 95th percentile - index, value and range */
-       qsort((void *)b->ba_data, n, sizeof (double), doublecmp);
-       min = b->ba_data[0] + 0.000001;
-       i95 = n * 95 / 100;
-       p95 = b->ba_data[i95];
-       r95 = p95 - min + 1;
-
-       /* find a suitable min and scale */
-       i = 0;
-       x = r95 / (HISTOSIZE - 1);
-       while (x >= 10.0) {
-               x /= 10.0;
-               i++;
-       }
-       y = x + 0.9999999999;
-       while (i > 0) {
-               y *= 10;
-               i--;
-       }
-       min /= y;
-       min *= y;
-       scale = y * (HISTOSIZE - 1);
-       if (scale < (HISTOSIZE - 1)) {
-               scale = (HISTOSIZE - 1);
-       }
-
-       /* create and initialise the histogram */
-       histo = malloc(HISTOSIZE * sizeof (histo_t));
-       for (i = 0; i < HISTOSIZE; i++) {
-               histo[i].sum = 0.0;
-               histo[i].count = 0;
-       }
-
-       /* populate the histogram */
-       last = 0;
-       sum = 0.0;
-       count = 0;
-       for (i = 0; i < i95; i++) {
-               j = (HISTOSIZE - 1) * (b->ba_data[i] - min) / scale;
-
-               if (j >= HISTOSIZE) {
-                       (void) printf("panic!\n");
-                       j = HISTOSIZE - 1;
-               }
-
-               histo[j].sum += b->ba_data[i];
-               histo[j].count++;
-
-               sum += b->ba_data[i];
-               count++;
-       }
-       m95 = sum / count;
-
-       /* find the larges bucket */
-       maxcount = 0;
-       for (i = 0; i < HISTOSIZE; i++)
-               if (histo[i].count > 0) {
-                       last = i;
-                       if (histo[i].count > maxcount)
-                               maxcount = histo[i].count;
-               }
-
-       /* print the buckets */
-       for (i = 0; i <= last; i++) {
-               (void) printf("#       %12lld %12.5f |", histo[i].count,
-                   (min + scale * (double)i / (HISTOSIZE - 1)));
-
-               print_bar(histo[i].count, maxcount);
-
-               if (histo[i].count > 0)
-                       (void) printf("%12.5f\n",
-                           histo[i].sum / histo[i].count);
-               else
-                       (void) printf("%12s\n", "-");
-       }
-
-       /* find the mean of values beyond the 95th percentile */
-       sum = 0.0;
-       count = 0;
-       for (i = i95; i < n; i++) {
-               sum += b->ba_data[i];
-               count++;
-       }
-
-       /* print the >95% bucket summary */
-       (void) printf("#\n");
-       (void) printf("#       %12lld %12s |", count, "> 95%");
-       print_bar(count, maxcount);
-       if (count > 0)
-               (void) printf("%12.5f\n", sum / count);
-       else
-               (void) printf("%12s\n", "-");
-       (void) printf("#\n");
-       (void) printf("#       %12s %12.5f\n", "mean of 95%", m95);
-       (void) printf("#       %12s %12.5f\n", "95th %ile", p95);
-
-       /* quantify any buffer overflow */
-       if (b->ba_batches > b->ba_datasize)
-               (void) printf("#       %12s %12d\n", "data dropped",
-                   b->ba_batches - b->ba_datasize);
-}
-
-static void
-compute_stats(barrier_t *b)
-{
-       int i;
-
-       if (b->ba_batches > b->ba_datasize)
-               b->ba_batches = b->ba_datasize;
-
-       /*
-        * convert to usecs/call
-        */
-
-       for (i = 0; i < b->ba_batches; i++)
-               b->ba_data[i] /= 1000.0;
-
-       /*
-        * do raw stats
-        */
-
-       (void) crunch_stats(b->ba_data, b->ba_batches, &b->ba_raw);
-
-       /*
-        * recursively apply 3 sigma rule to remove outliers
-        */
-
-       b->ba_corrected = b->ba_raw;
-       b->ba_outliers = 0;
-
-       if (b->ba_batches > 40) { /* remove outliers */
-               int removed;
-
-               do {
-                       removed = remove_outliers(b->ba_data, b->ba_batches,
-                           &b->ba_corrected);
-                       b->ba_outliers += removed;
-                       b->ba_batches -= removed;
-                       (void) crunch_stats(b->ba_data, b->ba_batches,
-                           &b->ba_corrected);
-                       } while (removed != 0 && b->ba_batches > 40);
-       }
-
-}
-
-/*
- * routine to compute various statistics on array of doubles.
- */
-
-static int
-crunch_stats(double *data, int count, stats_t *stats)
-{
-       double a;
-       double std;
-       double diff;
-       double sk;
-       double ku;
-       double mean;
-       int i;
-       int bytes;
-       double *dupdata;
-
-       /*
-        * first we need the mean
-        */
-
-       mean = 0.0;
-
-       for (i = 0; i < count; i++) {
-               mean += data[i];
-       }
-
-       mean /= count;
-
-       stats->st_mean = mean;
-
-       /*
-        * malloc and sort so we can do median
-        */
-
-       dupdata = malloc(bytes = sizeof (double) * count);
-       (void) memcpy(dupdata, data, bytes);
-       qsort((void *)dupdata, count, sizeof (double), doublecmp);
-       stats->st_median   = dupdata[count/2];
-
-       /*
-        * reuse dupdata to compute time correlation of data to
-        * detect interesting time-based trends
-        */
-
-       for (i = 0; i < count; i++)
-               dupdata[i] = (double)i;
-
-       (void) fit_line(dupdata, data, count, &a, &stats->st_timecorr);
-       free(dupdata);
-
-       std = 0.0;
-       sk  = 0.0;
-       ku  = 0.0;
-
-       stats->st_max = -1;
-       stats->st_min = 1.0e99; /* hard to find portable values */
-
-       for (i = 0; i < count; i++) {
-               if (data[i] > stats->st_max)
-                       stats->st_max = data[i];
-               if (data[i] < stats->st_min)
-                       stats->st_min = data[i];
-
-               diff = data[i] - mean;
-               std += diff * diff;
-               sk  += diff * diff * diff;
-               ku  += diff * diff * diff * diff;
-       }
-
-       stats->st_stddev   = std = sqrt(std/(double)(count - 1));
-       stats->st_stderr   = std / sqrt(count);
-       stats->st_99confidence = stats->st_stderr * 2.326;
-       stats->st_skew     = sk / (std * std * std) / (double)(count);
-       stats->st_kurtosis = ku / (std * std * std * std) /
-           (double)(count) - 3;
-
-       return (0);
-}
-
-/*
- * does a least squares fit to the set of points x, y and
- * fits a line y = a + bx.  Returns a, b
- */
-
-int
-fit_line(double *x, double *y, int count, double *a, double *b)
-{
-       double sumx, sumy, sumxy, sumx2;
-       double denom;
-       int i;
-
-       sumx = sumy = sumxy = sumx2 = 0.0;
-
-       for (i = 0; i < count; i++) {
-               sumx    += x[i];
-               sumx2   += x[i] * x[i];
-               sumy    += y[i];
-               sumxy   += x[i] * y[i];
-       }
-
-       denom = count * sumx2 - sumx * sumx;
-
-       if (denom == 0.0)
-               return (-1);
-
-       *a = (sumy * sumx2 - sumx * sumxy) / denom;
-
-       *b = (count * sumxy - sumx * sumy) / denom;
-
-       return (0);
-}
-
-/*
- * empty function for measurement purposes
- */
-
-int
-nop()
-{
-       return (1);
-}
-
-#define        NSECITER 1000
-
-static long long
-get_nsecs_overhead()
-{
-       long long s;
-
-       double data[NSECITER];
-       stats_t stats;
-
-       int i;
-       int count;
-       int outliers;
-
-       (void) getnsecs(); /* warmup */
-       (void) getnsecs(); /* warmup */
-       (void) getnsecs(); /* warmup */
-
-       i = 0;
-
-       count = NSECITER;
-
-       for (i = 0; i < count; i++) {
-               s = getnsecs();
-               data[i] = getnsecs() - s;
-       }
-
-       (void) crunch_stats(data, count, &stats);
-
-       while ((outliers = remove_outliers(data, count, &stats)) != 0) {
-               count -= outliers;
-               (void) crunch_stats(data, count, &stats);
-       }
-
-       return ((long long)stats.st_mean);
-
-}
-
-long long
-get_nsecs_resolution()
-{
-       long long y[1000];
-
-       int i, j, nops, res;
-       long long start, stop;
-
-       /*
-        * first, figure out how many nops to use
-        * to get any delta between time measurements.
-        * use a minimum of one.
-        */
-
-       /*
-        * warm cache
-        */
-
-       stop = start = getnsecs();
-
-       for (i = 1; i < 10000000; i++) {
-               start = getnsecs();
-               for (j = i; j; j--)
-                       ;
-               stop = getnsecs();
-               if (stop > start)
-                       break;
-       }
-
-       nops = i;
-
-       /*
-        * now collect data at linearly varying intervals
-        */
-
-       for (i = 0; i < 1000; i++) {
-               start = getnsecs();
-               for (j = nops * i; j; j--)
-                       ;
-               stop = getnsecs();
-               y[i] = stop - start;
-       }
-
-       /*
-        * find smallest positive difference between samples;
-        * this is the timer resolution
-        */
-
-       res = 1<<30;
-
-       for (i = 1; i < 1000; i++) {
-               int diff = y[i] - y[i-1];
-
-               if (diff > 0 && res > diff)
-                       res = diff;
-
-       }
-
-       return (res);
-}
-
-/*
- * remove any data points from the array more than 3 sigma out
- */
-
-static int
-remove_outliers(double *data, int count, stats_t *stats)
-{
-       double outmin = stats->st_mean - 3 * stats->st_stddev;
-       double outmax = stats->st_mean + 3 * stats->st_stddev;
-
-       int i, j, outliers;
-
-       for (outliers = i = j = 0; i < count; i++)
-               if (data[i] > outmax || data[i] < outmin)
-                       outliers++;
-               else
-                       data[j++] = data[i];
-
-       return (outliers);
-}
diff --git a/tools/tests/libMicro/libmicro.h b/tools/tests/libMicro/libmicro.h
deleted file mode 100644 (file)
index 0359134..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef LIBMICRO_H
-#define        LIBMICRO_H
-
-#include <pthread.h>
-
-#define        LIBMICRO_VERSION        "0.4.0"
-
-#define        STRSIZE                 1024
-
-#define STREQ(a,b) (strcmp(a,b) == 0)
-
-typedef struct {
-       long long               re_count;
-       long long               re_errors;
-       long long               re_t0;
-       long long               re_t1;
-} result_t;
-
-typedef struct {
-       double                  sum;
-       long long               count;
-} histo_t;
-
-#define        HISTOSIZE               32
-#define        DATASIZE                100000
-
-/*
- * stats we compute on data sets
- */
-
-typedef struct stats {
-       double  st_min;
-       double  st_max;
-       double  st_mean;
-       double  st_median;
-       double  st_stddev;
-       double  st_stderr;
-       double  st_99confidence;
-       double  st_skew;
-       double  st_kurtosis;
-       double  st_timecorr;    /* correlation with respect to time */
-} stats_t;
-
-/*
- * Barrier stuff
- */
-
-typedef struct {
-       int                     ba_hwm;         /* barrier setpoint     */
-       int                     ba_flag;        /* benchmark while true */
-       long long               ba_deadline;    /* when to stop         */
-       int                     ba_phase;       /* number of time used  */
-       int                     ba_waiters;     /* how many are waiting */
-
-#ifdef USE_SEMOP
-       int                     ba_semid;
-#else
-       pthread_mutex_t         ba_lock;
-       pthread_cond_t          ba_cv;
-#endif
-
-       long long               ba_count;       /* how many ops          */
-       long long               ba_errors;      /* how many errors       */
-
-       int                     ba_quant;       /* how many quant errors */
-       int                     ba_batches;     /* how many samples      */
-
-       double                  ba_starttime;   /* test time start */
-       double                  ba_endtime;     /* test time end */
-
-#ifdef NEVER
-       double                  ba_tmin;        /* min time taken */
-       double                  ba_tmax;        /* max time taken */
-       double                  ba_ctmax;       /* max after outliers */
-       double                  ba_mean;        /* average value */
-       double                  ba_median;      /* median value */
-       double                  ba_rawmedian;   /* raw median value */
-       double                  ba_stddev;      /* standard deviation */
-       double                  ba_stderr;      /* standard error */
-       double                  ba_skew;        /* skew */
-       double                  ba_kurtosis;    /* kurtosis */
-#endif
-       stats_t                 ba_raw;         /* raw stats */
-       stats_t                 ba_corrected;   /* corrected stats */
-
-       int                     ba_outliers;    /* outlier count */
-
-       long long               ba_t0;          /* first thread/proc */
-       long long               ba_t1;          /* time of last thread */
-       long long               ba_count0;
-       long long               ba_errors0;
-
-       int                     ba_datasize;    /* possible #items data */
-       double                  ba_data[1];     /* start of data ararry */
-} barrier_t;
-
-
-/*
- * Barrier interfaces
- */
-
-barrier_t *barrier_create(int hwm, int datasize);
-int barrier_destroy(barrier_t *bar);
-int barrier_queue(barrier_t *bar, result_t *res);
-
-
-/*
- * Functions that can be provided by the user
- */
-
-int    benchmark(void *tsd, result_t *res);
-int    benchmark_init();
-int    benchmark_fini();
-int    benchmark_initrun();
-int    benchmark_finirun();
-int    benchmark_initworker();
-int    benchmark_finiworker();
-int    benchmark_initbatch(void *tsd);
-int    benchmark_finibatch(void *tsd);
-int    benchmark_optswitch(int opt, char *optarg);
-char   *benchmark_result();
-
-
-/*
- * Globals exported to the user
- */
-
-extern int                     lm_argc;
-extern char                    **lm_argv;
-
-extern int                     lm_optB;
-extern int                     lm_optD;
-extern int                     lm_optH;
-extern char                    *lm_optN;
-extern int                     lm_optP;
-extern int                     lm_optS;
-extern int                     lm_optT;
-
-extern int                     lm_defB;
-extern int                     lm_defD;
-extern int                     lm_defH;
-extern char                    *lm_defN;
-extern int                     lm_defP;
-extern int                     lm_defS;
-extern int                     lm_defT;
-extern int                     lm_nsecs_per_op;
-
-extern char                    *lm_procpath;
-extern char                    lm_procname[STRSIZE];
-extern char                    lm_usage[STRSIZE];
-extern char                    lm_optstr[STRSIZE];
-extern char                    lm_header[STRSIZE];
-extern size_t                  lm_tsdsize;
-
-
-/*
- * Utility functions
- */
-
-int            getpindex();
-int            gettindex();
-void           *gettsd(int p, int t);
-#if defined(__APPLE__)
-int gettsdindex(void *arg);
-#endif /* __APPLE__ */
-long long      getusecs();
-long long      getnsecs();
-int            setfdlimit(int limit);
-long long      sizetoll();
-int            sizetoint();
-int            fit_line(double *, double *, int, double *, double *);
-long long      get_nsecs_resolution();
-
-
-/* Apple Mods Here */
-
-
-
-#ifdef  NO_PORTMAPPER
-#define TCP_SELECT      -31233
-#define TCP_XACT        -31234
-#define TCP_CONTROL     -31235
-#define TCP_DATA        -31236
-#define TCP_CONNECT     -31237
-#define UDP_XACT        -31238
-#define UDP_DATA        -31239
-#else
-#define TCP_SELECT      (u_long)404038  /* XXX - unregistered */
-#define TCP_XACT        (u_long)404039  /* XXX - unregistered */
-#define TCP_CONTROL     (u_long)404040  /* XXX - unregistered */
-#define TCP_DATA        (u_long)404041  /* XXX - unregistered */
-#define TCP_CONNECT     (u_long)404042  /* XXX - unregistered */
-#define UDP_XACT        (u_long)404032  /* XXX - unregistered */
-#define UDP_DATA        (u_long)404033  /* XXX - unregistered */
-#define VERS            (u_long)1
-#endif
-/*
-* socket send/recv buffer optimizations
-*/
-#define SOCKOPT_READ    0x0001
-#define SOCKOPT_WRITE   0x0002
-#define SOCKOPT_RDWR    0x0003
-#define SOCKOPT_PID     0x0004
-#define SOCKOPT_REUSE   0x0008
-#define SOCKOPT_NONE    0
-
-#ifndef SOCKBUF
-#define SOCKBUF         (1024*1024)
-#endif
-
-#ifndef XFERSIZE
-#define XFERSIZE        (64*1024)       /* all bandwidth I/O should use this */
-#endif
-
-typedef unsigned long iter_t;
-
-int     tcp_server(int prog, int rdwr);
-int     tcp_done(int prog);
-int     tcp_accept(int sock, int rdwr);
-int     tcp_connect(char *host, int prog, int rdwr);
-void    sock_optimize(int sock, int rdwr);
-int     sockport(int s);
-
-/* end Apple Mods */
-       
-
-#endif /* LIBMICRO_H */
diff --git a/tools/tests/libMicro/libmicro_main.c b/tools/tests/libMicro/libmicro_main.c
deleted file mode 100644 (file)
index f7bcde1..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Separate file for main so we can link other programs
- * with libmicro
- */
-
-#include <stdlib.h>
-
-extern int actual_main(int, char **);
-
-int
-main(int argc, char *argv[])
-{
-       return (actual_main(argc, argv));
-}
diff --git a/tools/tests/libMicro/listen.c b/tools/tests/libMicro/listen.c
deleted file mode 100644 (file)
index f8730d7..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * listen benchmark
- */
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-#define        FIRSTPORT               12345
-
-static struct sockaddr_in      adds;
-static int                     sock = -1;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures listen()()\n");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     j;
-       int                     opt = 1;
-       struct hostent  *host;
-
-       sock = socket(AF_INET, SOCK_STREAM, 0);
-       if (sock == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-           &opt, sizeof (int)) == -1) {
-               perror("setsockopt");
-               exit(1);
-       }
-
-       if ((host = gethostbyname("localhost")) == NULL) {
-               perror("gethostbyname");
-               exit(1);
-       }
-
-       j = FIRSTPORT;
-       for (;;) {
-               (void) memset(&adds, 0, sizeof (struct sockaddr_in));
-               adds.sin_family = AF_INET;
-               adds.sin_port = htons(j++);
-               (void) memcpy(&adds.sin_addr.s_addr, host->h_addr_list[0],
-                   sizeof (struct in_addr));
-
-               if (bind(sock, (struct sockaddr *)&adds,
-                   sizeof (struct sockaddr_in)) == 0) {
-                       break;
-               }
-
-               if (errno != EADDRINUSE) {
-                       perror("bind");
-                       exit(1);
-               }
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i += 2) {
-               if (listen(sock, 4) == -1)
-                       res->re_errors++;
-               if (listen(sock, 5) == -1)
-                       res->re_errors++;
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/localtime_r.c b/tools/tests/libMicro/localtime_r.c
deleted file mode 100644 (file)
index 8430884..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * localtime benchmark
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures localtime_r()\n");
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct tm               tms;
-       static time_t           clock1 = 0L;
-       static time_t           clock2 = 1L;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) localtime_r(&clock1, &tms);
-               (void) localtime_r(&clock2, &tms);
-               (void) localtime_r(&clock1, &tms);
-               (void) localtime_r(&clock2, &tms);
-               (void) localtime_r(&clock1, &tms);
-               (void) localtime_r(&clock2, &tms);
-               (void) localtime_r(&clock1, &tms);
-               (void) localtime_r(&clock2, &tms);
-               (void) localtime_r(&clock1, &tms);
-               (void) localtime_r(&clock2, &tms);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/log.c b/tools/tests/libMicro/log.c
deleted file mode 100644 (file)
index 71910e0..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * log benchmark - should do wider range...
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures log()");
-       lm_nsecs_per_op = 75;
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       /* Added as part of the fix for radar 7508837 */
-        double                  t = 0.0;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               double value = i + .01;
-#if 1 /* Apple added code, see radar 7508837 */
-                t += log(value);
-                t += log(value + 1.0);
-                t += log(value + 2.0);
-                t += log(value + 3.0);
-                t += log(value + 4.0);
-                t += log(value + 5.0);
-                t += log(value + 6.0);
-                t += log(value + 7.0);
-                t += log(value + 8.0);
-                t += log(value + 9.0);
-        }
-        res->re_count = i;
-
-        return ((int)(t - t));
-#else
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-               (void) log(value);
-       }
-       res->re_count = i;
-
-       return (0);
-#endif /* end of Apple fix  */
-}
diff --git a/tools/tests/libMicro/longjmp.c b/tools/tests/libMicro/longjmp.c
deleted file mode 100644 (file)
index 43c54d4..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark longjmp
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <setjmp.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures longjmp()\n");
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-#if 1  /* Apple fix to longjmp/siglongjmp tests, see radar 7440118 */
-       volatile int            i = 0;
-#else 
-       int i = 0;
-#endif /*end of Apple fix */
-       
-       jmp_buf                 env;
-
-       (void) setjmp(env);
-       i++;
-       if (i < lm_optB)
-               longjmp(env, 0);
-
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/lrand48.c b/tools/tests/libMicro/lrand48.c
deleted file mode 100644 (file)
index e82ddfd..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * lrand48
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures lrand48()");
-       lm_nsecs_per_op = 10;
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-               (void) lrand48();
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/lseek.c b/tools/tests/libMicro/lseek.c
deleted file mode 100644 (file)
index 6ca4af4..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * lseek
- */
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/dev/zero"
-#define        DEFS                    1024
-
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-
-typedef struct {
-       int                     ts_once;
-       int                     ts_fd;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:s:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-read (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "notes: measures lseek()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_fd = open(optf, O_RDONLY);
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i += 2) {
-               if (lseek(ts->ts_fd, 0L, SEEK_SET) != 0) {
-                       res->re_errors++;
-               }
-               if (lseek(ts->ts_fd, opts, SEEK_SET) != opts) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/malloc.c b/tools/tests/libMicro/malloc.c
deleted file mode 100644 (file)
index 1e25680..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * malloc benchmark (crude)
- */
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-static int             optg = 100;
-static int             opts[32] = {32};
-static int             optscnt = 0;
-
-typedef struct {
-       void                    **ts_glob;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:g:");
-
-       (void) sprintf(lm_usage,
-           "       [-g number of mallocs before free (default %d)]\n"
-           "       [-s size to malloc (default %d)."
-           "  Up to 32 sizes accepted\n"
-           "notes: measures malloc()/free()",
-           optg, opts[0]);
-
-       (void) sprintf(lm_header, "%6s %6s", "glob", "sizes");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       int tmp;
-       switch (opt) {
-       case 'g':
-               optg = sizetoint(optarg);
-               break;
-       case 's':
-               opts[optscnt] = sizetoint(optarg);
-               tmp = ((++optscnt) & (0x1F));
-               optscnt = tmp;
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (optscnt == 0)
-               optscnt = 1;
-
-       ts->ts_glob = malloc(sizeof (void *)* optg);
-       if (ts->ts_glob == NULL) {
-               return (1);
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j, k;
-
-       for (i = 0; i < lm_optB; i++) {
-               for (k = j = 0; j < optg; j++) {
-                       if ((ts->ts_glob[j] = malloc(opts[k++])) == NULL)
-                               res->re_errors++;
-                       if (k >= optscnt)
-                               k = 0;
-               }
-               for (j = 0; j < optg; j++) {
-                       free(ts->ts_glob[j]);
-               }
-       }
-
-       res->re_count = i * j;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char  result[256];
-       int i;
-
-       (void) sprintf(result, "%6d ", optg);
-
-       for (i = 0; i < optscnt; i++)
-               (void) sprintf(result + strlen(result), "%d ", opts[i]);
-       return (result);
-}
diff --git a/tools/tests/libMicro/memcpy.c b/tools/tests/libMicro/memcpy.c
deleted file mode 100644 (file)
index 9a9448c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * memcpy
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-#define        DEFS                    8192
-#define        DEFR                    1
-
-static long long               opts = DEFS;
-static int                     optf;
-static int                     optt;
-static int                     opta;
-
-typedef struct {
-       char                    *ts_src;
-       char                    *ts_dest;
-       int                     ts_srcsize;
-       int                     ts_destsize;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "a:s:ft");
-
-       (void) sprintf(lm_usage,
-           "       [-s buffer-size (default %d)]\n"
-           "       [-a relative alignment (default page aligned)]\n"
-           "       [-f (rotate \"from\" buffer to keep it out of cache)]\n"
-           "       [-t (rotate \"to\" buffer to keep it out of cache)]\n"
-           "notes: measures memcpy()\n",
-           DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf++;
-               break;
-       case 't':
-               optt++;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       case 'a':
-               opta = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (optf)
-               ts->ts_srcsize = 64 * 1024 * 1024;
-       else
-               ts->ts_srcsize = opts + opta;
-
-       if (optt)
-               ts->ts_destsize = 64 * 1024 * 1024;
-       else
-               ts->ts_destsize = (int)opts;
-
-
-       ts->ts_src = opta + (char *)valloc(ts->ts_srcsize);
-       ts->ts_dest = valloc(ts->ts_destsize);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       char                    *src = ts->ts_src;
-       char                    *dest = ts->ts_dest;
-
-       int bump = (int)opts;
-
-       if (bump < 1024)
-               bump = 1024; /* avoid prefetched area */
-       for (i = 0; i < lm_optB; i++) {
-               (void) memcpy(dest, src, opts);
-               if (optf) {
-                       src += bump;
-                       if (src + opts > ts->ts_src + ts->ts_srcsize)
-                               src = ts->ts_src;
-               }
-               if (optt) {
-                       dest += bump;
-                       if (dest + opts > ts->ts_dest + ts->ts_destsize)
-                               dest = ts->ts_dest;
-               }
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/memmove.c b/tools/tests/libMicro/memmove.c
deleted file mode 100644 (file)
index 822c885..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * memmove
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-#define        DEFS                    8192
-#define        DEFR                    1
-
-static long long               opts = DEFS;
-static int                     optf;
-static int                     optt;
-static int                     opta;
-
-typedef struct {
-       char                    *ts_src;
-       char                    *ts_dest;
-       int                     ts_srcsize;
-       int                     ts_destsize;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "a:s:ft");
-
-       (void) sprintf(lm_usage,
-           "       [-s buffer-size (default %d)]\n"
-           "       [-a relative alignment (default page aligned)]\n"
-           "       [-f (rotate \"from\" buffer to keep it out of cache)]\n"
-           "       [-t (rotate \"to\" buffer to keep it out of cache)]\n"
-           "notes: measures memmove()\n",
-           DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf++;
-               break;
-       case 't':
-               optt++;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       case 'a':
-               opta = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (optf)
-               ts->ts_srcsize = 64 * 1024 * 1024;
-       else
-               ts->ts_srcsize = opts + opta;
-
-       if (optt)
-               ts->ts_destsize = 64 * 1024 * 1024;
-       else
-               ts->ts_destsize = (int)opts;
-
-
-       ts->ts_src = opta + (char *)valloc(ts->ts_srcsize);
-       ts->ts_dest = valloc(ts->ts_destsize);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       char                    *src = ts->ts_src;
-       char                    *dest = ts->ts_dest;
-
-       int bump = (int)opts;
-
-       if (bump < 1024)
-               bump = 1024; /* avoid prefetched area */
-       for (i = 0; i < lm_optB; i++) {
-               (void) memmove(dest, src, opts);
-               if (optf) {
-                       src += bump;
-                       if (src + opts > ts->ts_src + ts->ts_srcsize)
-                               src = ts->ts_src;
-               }
-               if (optt) {
-                       dest += bump;
-                       if (dest + opts > ts->ts_dest + ts->ts_destsize)
-                               dest = ts->ts_dest;
-               }
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/memrand.c b/tools/tests/libMicro/memrand.c
deleted file mode 100644 (file)
index 8a9ccf3..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * memory access time check
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-static long    opts = 1024*1024;
-
-typedef struct {
-       long                    **ts_data;
-       long                    ts_result;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:");
-
-       (void) sprintf(lm_usage,
-           "       [-s size] number of bytes to "
-           " access (default %ld)\n"
-           "notes: measures \"random\" memory access times\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 's':
-               opts = sizetoint(optarg);
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int i, j;
-
-       ts->ts_data = malloc(opts);
-
-       if (ts->ts_data == NULL) {
-               return (1);
-       }
-
-       /*
-        * use lmbench style backwards stride
-        */
-
-       for (i = 0; i < opts / sizeof (long); i++) {
-               j = i - 128;
-               if (j < 0)
-                       j = j + opts / sizeof (long);
-               ts->ts_data[i] = (long *)&(ts->ts_data[j]);
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       long **ptr = ts->ts_data;
-
-
-
-       for (i = 0; i < lm_optB; i += 10) {
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-               ptr = (long **)*ptr;
-       }
-
-       ts->ts_result = (long)*ptr;
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char  result[256];
-
-       (void) sprintf(result, "%8ld ", opts);
-
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/memset.c b/tools/tests/libMicro/memset.c
deleted file mode 100644 (file)
index 8a63454..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * memset
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-#define        DEFS                    8192
-
-static long long               opts = DEFS;
-static int                     opta = 0;
-static int                     optu = 0;
-
-static char                    *optas = "4k";
-
-typedef struct {
-       char                    *ts_buff;
-       int                     ts_size;
-       int                     ts_offset;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "a:us:");
-
-       (void) sprintf(lm_usage,
-           "       [-s buffer-size (default %d)]\n"
-           "       [-a alignment (force buffer alignment)]\n"
-           "       [-u (try to always use uncached memory)]"
-           "notes: measures memset()\n",
-           DEFS);
-
-       (void) sprintf(lm_header, "%8s%16s", "size", "alignment");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'u':
-               optu = 1;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       case 'a':
-               opta = sizetoll(optarg);
-               if (opta > 4096)
-                       opta = 0;
-               else
-                       optas = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     errors = 0;
-       int i;
-
-       if (optu) {
-               ts->ts_size     = 1024 * 1024 * 64;
-               ts->ts_offset   = opta;
-       } else {
-               ts->ts_size     = opta + opts;
-               ts->ts_offset   = opta;
-       }
-
-       if ((ts->ts_buff = (char *)valloc(ts->ts_size)) == NULL)
-               errors++;
-
-       for (i = 0; i < ts->ts_size; i++)
-               ts->ts_buff[i] = 0;
-       return (errors);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-
-       if (optu) {
-               char *buf = ts->ts_buff + ts->ts_offset;
-               char *end = ts->ts_buff + ts->ts_size;
-               int offset = ts->ts_offset;
-               
-               unsigned long tmp;
-
-               for (i = 0; i < lm_optB; i ++) {
-                       (void) memset(buf, 0, opts);
-                       tmp = (((unsigned long)buf + opts + 4095) & ~4095) + offset;
-                       buf = (char *) tmp;
-                       if (buf + opts > end)
-                               buf = ts->ts_buff + offset;
-               }
-       } else {
-               char *buf = ts->ts_buff + ts->ts_offset;
-
-               for (i = 0; i < lm_optB; i += 10) {
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-                       (void) memset(buf, 0, opts);
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld%12s", opts, optas);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/mk_tarball b/tools/tests/libMicro/mk_tarball
deleted file mode 100755 (executable)
index fcac23e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh -x
-#
-# Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-#
-# script to make tarball... args are contents to be inserted
-#
-
-libmicro_version=`bin/getpid -V`
-case $libmicro_version in
-[0-9]*)
-       ;;
-*)
-       echo "ERROR: cannot determine libMicro version"
-       exit 1
-esac
-dirname="libMicro-$libmicro_version"
-
-here=`pwd`
-target=$here/libMicro.tar
-tmpdir=/private/tmp/libmicro.$$
-mkdir -p $tmpdir/$dirname
-cp $* $tmpdir/$dirname
-cd $tmpdir
-tar cvf $target $dirname
-cd $here
-rm -rf $tmpdir
diff --git a/tools/tests/libMicro/mktime.c b/tools/tests/libMicro/mktime.c
deleted file mode 100644 (file)
index 9738ce5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * mktime
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       struct tm       ts_tm1;
-       struct tm       ts_tm2;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "notes: measures mktime()\n");
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       time_t          clock1;
-       time_t          clock2;
-
-       clock1 = time(NULL);
-       clock2 = clock1 + 1;
-
-       (void) localtime_r(&clock1, &ts->ts_tm1);
-       (void) localtime_r(&clock2, &ts->ts_tm2);
-
-       return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       struct tm               t1, t2;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               t1 = ts->ts_tm1;
-               t2 = ts->ts_tm2;
-               (void) mktime(&t1);
-               (void) mktime(&t2);
-
-               t1 = ts->ts_tm1;
-               t2 = ts->ts_tm2;
-               (void) mktime(&t1);
-               (void) mktime(&t2);
-
-               t1 = ts->ts_tm1;
-               t2 = ts->ts_tm2;
-               (void) mktime(&t1);
-               (void) mktime(&t2);
-
-               t1 = ts->ts_tm1;
-               t2 = ts->ts_tm2;
-               (void) mktime(&t1);
-               (void) mktime(&t2);
-
-               t1 = ts->ts_tm1;
-               t2 = ts->ts_tm2;
-               (void) mktime(&t1);
-               (void) mktime(&t2);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/mmap.c b/tools/tests/libMicro/mmap.c
deleted file mode 100644 (file)
index 44b8b58..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/mman.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <strings.h>
-
-#include "libmicro.h"
-
-typedef volatile char          vchar_t;
-
-typedef struct {
-       int                     ts_once;
-       vchar_t **              ts_map;
-       vchar_t                 ts_foo;
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFL                    8192
-
-static char                    *optf = DEFF;
-static long long               optl = DEFL;
-static int                     optr = 0;
-static int                     opts = 0;
-static int                     optw = 0;
-static int                     fd = -1;
-static int                     anon = 0;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:l:rsw");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-map (default %s)]\n"
-           "       [-l mapping-length (default %d)]\n"
-           "       [-r] (read a byte from each page)\n"
-           "       [-w] (write a byte on each page)\n"
-           "       [-s] (use MAP_SHARED)\n"
-           "notes: measures mmap()\n",
-           DEFF, DEFL);
-
-       (void) sprintf(lm_header, "%8s %5s", "length", "flags");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               anon = strcmp(optf, "MAP_ANON") == 0;
-               break;
-       case 'l':
-               optl = sizetoll(optarg);
-               break;
-       case 'r':
-               optr = 1;
-               break;
-       case 's':
-               opts = 1;
-               break;
-       case 'w':
-               optw = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       if (!anon)
-               fd = open(optf, O_RDWR);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_map = (vchar_t **)malloc(lm_optB * sizeof (void *));
-               if (ts->ts_map == NULL) {
-                       errors++;
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (anon) {
-                       ts->ts_map[i] = (vchar_t *)mmap(NULL, optl,
-                           PROT_READ | PROT_WRITE,
-                           MAP_ANON | (opts ? MAP_SHARED : MAP_PRIVATE),
-                           -1, 0L);
-               } else {
-                       ts->ts_map[i] = (vchar_t *)mmap(NULL, optl,
-                           PROT_READ | PROT_WRITE,
-                           opts ? MAP_SHARED : MAP_PRIVATE,
-                           fd, 0L);
-               }
-
-               if (ts->ts_map[i] == MAP_FAILED) {
-                       res->re_errors++;
-                       continue;
-               }
-
-               if (optr) {
-                       for (j = 0; j < optl; j += 4096) {
-                               ts->ts_foo += ts->ts_map[i][j];
-                       }
-               }
-               if (optw) {
-                       for (j = 0; j < optl; j += 4096) {
-                               ts->ts_map[i][j] = 1;
-                       }
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) munmap((void *)ts->ts_map[i], optl);
-       }
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-       char                    flags[5];
-
-       flags[0] = anon ? 'a' : '-';
-       flags[1] = optr ? 'r' : '-';
-       flags[2] = optw ? 'w' : '-';
-       flags[3] = opts ? 's' : '-';
-       flags[4] = 0;
-
-       (void) sprintf(result, "%8lld %5s", optl, flags);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/mprotect.c b/tools/tests/libMicro/mprotect.c
deleted file mode 100644 (file)
index db6ecaa..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <strings.h>
-
-#include "libmicro.h"
-
-typedef volatile char          vchar_t;
-
-typedef struct {
-       int                     ts_batch;
-       int                     ts_res;
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFL                    8192
-
-static char                    *optf = DEFF;
-static long long               optl = DEFL;
-static int                     optr = 0;
-static int                     optw = 0;
-static int                     opts = 0;
-static int                     optt = 0;
-static int                     fd = -1;
-static int                     anon = 0;
-static int                     foo = 0;
-static vchar_t                 *seg;
-static int                     pagesize;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:l:rstw");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-map (default %s)]\n"
-           "       [-l mapping-length (default %d)]\n"
-           "       [-r] (read a byte from each page)\n"
-           "       [-w] (write a byte on each page)\n"
-           "       [-s] (use MAP_SHARED)\n"
-           "       [-t] (touch each page after restoring permissions)\n"
-           "notes: measures mprotect()\n",
-           DEFF, DEFL);
-
-       (void) sprintf(lm_header, "%8s %5s", "size", "flags");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               anon = strcmp(optf, "MAP_ANON") == 0;
-               break;
-       case 'l':
-               optl = sizetoll(optarg);
-               break;
-       case 'r':
-               optr = 1;
-               break;
-       case 's':
-               opts = 1;
-               break;
-       case 't':
-               optt = 1;
-               break;
-       case 'w':
-               optw = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     flags;
-       int                     i;
-
-       if (!anon)
-               fd = open(optf, O_RDWR);
-
-       flags = opts ? MAP_SHARED : MAP_PRIVATE;
-       flags |= anon ? MAP_ANON : 0;
-
-       seg = (vchar_t *)mmap(NULL, lm_optB * optl, PROT_READ | PROT_WRITE,
-           flags, anon ? -1 : fd, 0L);
-
-       if (seg == MAP_FAILED) {
-               return (-1);
-       }
-
-       if (optr) {
-               for (i = 0; i < lm_optB * optl; i += 4096) {
-                       foo += seg[i];
-               }
-       }
-
-       if (optw) {
-               for (i = 0; i < lm_optB * optl; i += 4096) {
-                       seg[i] = 1;
-               }
-       }
-
-       pagesize = getpagesize();
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     us;
-       int                     prot = PROT_NONE;
-       int                     j, k;
-
-#if !defined(__APPLE__)
-    us = (getpindex() * lm_optT) + gettindex();
-#else
-    us = gettsdindex(tsd);
-#endif /* __APPLE__ */
-       
-       for (i = 0; i < lm_optB; i++) {
-               switch ((us + ts->ts_batch + i) % 2) {
-               case 0:
-                       prot = PROT_NONE;
-                       if (optt) {
-                               for (j = k = 0; j < optl; j += pagesize)
-                                       k += seg[i * optl + j];
-                               ts->ts_res += k;
-                       }
-                       break;
-               default:
-                       prot = PROT_READ | PROT_WRITE;
-                       break;
-               }
-
-               if (mprotect((void *)&seg[i * optl], optl, prot) == -1) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count += lm_optB;
-       ts->ts_batch++;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-       char                    flags[6];
-
-       flags[0] = anon ? 'a' : '-';
-       flags[1] = optr ? 'r' : '-';
-       flags[2] = optw ? 'w' : '-';
-       flags[3] = opts ? 's' : '-';
-       flags[4] = optt ? 't' : '-';
-       flags[5] = 0;
-
-       (void) sprintf(result, "%8lld %5s", optl, flags);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/msync.c b/tools/tests/libMicro/msync.c
deleted file mode 100644 (file)
index 48b0510..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/mman.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <strings.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       char                    *ts_map;
-       int                     ts_foo; /* defeat optimizers */
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFL                    8192
-
-static char                    *optf = DEFF;
-static long long               optl = DEFL;
-static int                     optr = 0;
-static int                     opts = 0;
-static int                     optw = 0;
-static int                     opta = MS_SYNC;
-static int                     opti = 0;
-static int                     anon = 0;
-static int                     pagesize;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "af:il:rsw");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-map (default %s)]\n"
-           "       [-l mapping-length (default %d)]\n"
-           "       [-r] (read a byte from each page between msyncs)\n"
-           "       [-w] (write a byte to each page between msyncs)\n"
-           "       [-s] (use MAP_SHARED instead of MAP_PRIVATE)\n"
-           "       [-a (specify MS_ASYNC rather than default MS_SYNC)\n"
-           "       [-i (specify MS_INVALIDATE)\n"
-           "notes: measures msync()\n",
-           DEFF, DEFL);
-
-       (void) sprintf(lm_header, "%8s %6s", "length", "flags");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'a':
-               opta = MS_ASYNC;
-               break;
-
-       case 'f':
-               optf = optarg;
-               break;
-
-       case 'i':
-               opti = MS_INVALIDATE;
-               break;
-
-       case 'l':
-               optl = sizetoll(optarg);
-               break;
-       case 'r':
-               optr = 1;
-               break;
-       case 's':
-               opts = 1;
-               break;
-       case 'w':
-               optw = 1;
-               break;
-       default:
-               return (-1);
-       }
-
-       pagesize = getpagesize();
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       int fd;
-
-       if ((fd = open(optf, O_RDWR)) < 0) {
-               perror("open:");
-               return (1);
-       }
-
-       (void) ftruncate(fd, optl);
-
-       if ((ts->ts_map = (char *)mmap(NULL, optl,
-           PROT_READ | PROT_WRITE, opts ? MAP_SHARED : MAP_PRIVATE,
-           fd, 0L)) == MAP_FAILED) {
-               perror("mmap:");
-               (void) close(fd);
-               return (1);
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j;
-
-       for (i = 0; i < lm_optB; i++) {
-
-               if (msync(ts->ts_map, optl, opta | opti) < 0) {
-                       perror("msync:");
-                       res->re_errors++;
-                       break;
-               }
-
-               if (optr) {
-                       for (j = 0; j < optl; j += pagesize) {
-                               ts->ts_foo += ts->ts_map[j];
-                       }
-               }
-
-               if (optw) {
-                       for (j = 0; j < optl; j += pagesize) {
-                               ts->ts_map[j] = 1;
-                       }
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-       char                    flags[6];
-
-       flags[0] = anon ? 'a' : '-';
-       flags[1] = optr ? 'r' : '-';
-       flags[2] = optw ? 'w' : '-';
-       flags[3] = opts ? 's' : '-';
-       flags[4] = opti ? 'i' : '-';
-       flags[5] = 0;
-
-       (void) sprintf(result, "%8lld %6s", optl, flags);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/multiview.sh b/tools/tests/libMicro/multiview.sh
deleted file mode 100755 (executable)
index c1608f0..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-#!/bin/sh
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# output html comparison of several libmicro output data files
-# usage: multiview file1 file2 file3 file4 ...
-#
-#      relative ranking is calculated using first as reference
-#      color interpolation is done to indicate relative performance;
-#      the redder the color, the slower the result, the greener the
-#       faster
-awk '  BEGIN { 
-  benchmark_count = 0;
-  header_count = 0;
-}
-/^#/ {
-       next;
-       }
-/errors/ {
-       next;
-       }
-/^\!/ { 
-       split($0, A_header, ":"); 
-       name = substr(A_header[1],2);
-       headers[name]=name; 
-       header_data[name,FILENAME] = substr($0, length(name) + 3);
-       if (header_names[name] == 0) {
-               header_names[name] = ++header_count;
-               headers[header_count] = name;
-       }
-       next;
-}
-
-       { 
-       if(NF >= 7) {
-               if (benchmark_names[$1] == 0) {
-                       benchmark_names[$1] = ++benchmark_count;
-                       benchmarks[benchmark_count] = $1;
-               }
-               if ($6 == 0)
-                       benchmark_data[$1,FILENAME] = $4;
-               else 
-                       benchmark_data[$1,FILENAME] = -1;
-       }
-}          
-
-END { 
-       printf("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n");
-       printf("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
-       printf("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n");
-       printf("<head>\n");
-       printf("<meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\" />\n");
-       printf("<meta name=\"author\" content=\"autogen\" />\n");
-       printf("<title>multiview comparison</title>\n")
-       printf("<style type=\"text/css\">\n");
-       printf("body { font-family: sans-serif; }\n");
-       printf("table { border-collapse: collapse; }\n");
-       printf("td { padding: 0.1em; border: 1px solid #ccc; text-align: right; }\n");
-       printf("td.header { text-align: left; }\n");
-       printf("pre { margin-top: 0em; margin-bottom: 0em; }\n");
-       printf("</style>\n");
-       printf("</head>\n");
-       printf("<body bgcolor=\"#ffffff\" link=\"#0000ee\" vlink=\"#cc0000\" alink=\"#0000ee\">\n");
-       printf("<table border=\"1\" cellspacing=\"1\">\n");
-       printf("<tbody>\n");
-       for(i = 1; i <= header_count; i++) {
-               hname = headers[i];
-               printf("<tr><td class=\"header\">%s</td>\n", hname);
-               
-               for (j = 1; j < ARGC; j++) {
-                       sub("^[\t ]+", "", header_data[hname, ARGV[j]]);
-                       printf("<td class=\"header\">%s</td>\n", header_data[hname, ARGV[j]]);
-               }
-               printf("</tr>\n");
-       }
-       printf("<tr>\n");
-       printf("<th>BENCHMARK</th>\n");
-       printf("<th align=\"right\">USECS</th>\n");
-
-       for (i = 2; i < ARGC; i++) 
-               printf("<th align=\"right\">USECS [percentage]</th>\n");
-
-       printf("</tr>\n");
-       for(i = 1; i < benchmark_count; i++) {
-         for(j = 1; j < benchmark_count; j++) {
-           if (benchmarks[j] > benchmarks[j + 1]) {
-             tmp = benchmarks[j]; 
-             benchmarks[j] =  benchmarks[j+1];
-             benchmarks[j+1] = tmp;
-           }
-         }
-       }
-
-       for(i = 1; i <= benchmark_count; i++) {
-               name = benchmarks[i];
-               a = benchmark_data[name, ARGV[1]];
-
-               printf("<tr>\n");
-               printf("<td>%s</td>\n", name);
-               if (a > 0)
-                       printf("<td><pre>%f</pre></td>\n", a);
-               else {
-                       if (a < 0)
-                               printf("<td bgcolor=\"#ff0000\">%s</td>\n", "ERRORS");
-                       else 
-                               printf("<td>%s</td>\n", "missing");
-                               
-                       for (j = 2; j < ARGC; j++) 
-                               printf("<td>%s</td>\n", "not computed");
-                       continue;
-               }
-
-               for (j = 2; j < ARGC; j++) {
-                       b = benchmark_data[name, ARGV[j]];
-                       if (b > 0) {
-                               factor = b/a;
-                               bgcolor = colormap(factor);
-                               if (factor > 1)
-                                 percentage = -(factor * 100 - 100);
-                               if (factor <= 1)
-                                 percentage = 100/factor - 100;
-                               
-                               printf("<td bgcolor=\"%s\"><pre>%11.5f[%#+7.1f%%]</pre></td>\n", 
-                                       bgcolor, b, percentage);
-                       }
-                       
-                       else if (b < 0) 
-                               printf("<td bgcolor=\"#ff0000\">%s</td>\n", "ERRORS");
-                       else
-                               printf("<td>%25s</td>\n", "missing");
-                       
-               }
-               printf("</tr>\n");
-
-       }
-       printf("</tbody></table></body></html>\n");
-
-} 
-
-function colormap(value, bgcolor, r, g, b) 
-{      
-       if (value <= .2)
-               value = .2;
-       if (value > 5)
-               value = 5;
-
-       if (value < .9) {
-               r = colorcalc(.2, value, .9, 0, 255);
-               g = colorcalc(.2, value, .9, 153, 255);
-               b = colorcalc(.2, value, .9, 0, 255);
-               bgcolor=sprintf("#%2.2x%2.2x%2.2x",  r, g, b);
-       }
-       else if (value < 1.1)
-               bgcolor="#ffffff";
-       else {
-               r = 255;
-               g = colorcalc(1.1, value, 5, 255, 0);
-               b = colorcalc(1.1, value, 5, 255, 0);
-               bgcolor=sprintf("#%2.2x%2.2x%2.2x",  r, g, b);
-       }
-
-       return (bgcolor);
-}
-
-function colorcalc(min, value, max, mincolor, maxcolor)
-{
-        return((value - min)/(max-min) * (maxcolor-mincolor) + mincolor);
-}
-
-' "$@"
-
-
diff --git a/tools/tests/libMicro/munmap.c b/tools/tests/libMicro/munmap.c
deleted file mode 100644 (file)
index 7979dbb..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <strings.h>
-
-#include "libmicro.h"
-
-typedef volatile char          vchar_t;
-
-typedef struct {
-       int                     ts_once;
-       vchar_t **              ts_map;
-       vchar_t                 ts_foo;
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFL                    8192
-
-static char                    *optf = DEFF;
-static long long               optl = DEFL;
-static int                     optr = 0;
-static int                     optw = 0;
-static int                     opts = 0;
-static int                     fd = -1;
-static int                     anon = 0;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:l:rsw");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-map (default %s)]\n"
-           "       [-l mapping-length (default %d)]\n"
-           "       [-r] (read a byte from each page)\n"
-           "       [-w] (write a byte on each page)\n"
-           "       [-s] (use MAP_SHARED)\n"
-           "notes: measures munmap()\n",
-           DEFF, DEFL);
-
-       (void) sprintf(lm_header, "%8s %5s", "size", "flags");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               anon = strcmp(optf, "MAP_ANON") == 0;
-               break;
-       case 'l':
-               optl = sizetoll(optarg);
-               break;
-       case 'r':
-               optr = 1;
-               break;
-       case 's':
-               opts = 1;
-               break;
-       case 'w':
-               optw = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       if (!anon)
-               fd = open(optf, O_RDWR);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i, j;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_map = (vchar_t **)malloc(lm_optB * sizeof (void *));
-               if (ts->ts_map == NULL) {
-                       errors++;
-               }
-       }
-
-       for (i = 0; i < lm_optB; i++) {
-               if (anon) {
-                       ts->ts_map[i] = (vchar_t *)mmap(NULL, optl,
-                           PROT_READ | PROT_WRITE,
-                           MAP_ANON | (opts ? MAP_SHARED : MAP_PRIVATE),
-                           -1, 0L);
-               } else {
-                       ts->ts_map[i] = (vchar_t *)mmap(NULL, optl,
-                           PROT_READ | PROT_WRITE,
-                           opts ? MAP_SHARED : MAP_PRIVATE,
-                           fd, 0L);
-               }
-
-               if (ts->ts_map[i] == MAP_FAILED) {
-                       errors++;
-                       continue;
-               }
-               if (optr) {
-                       for (j = 0; j < optl; j += 4096) {
-                               ts->ts_foo += ts->ts_map[i][j];
-                       }
-               }
-               if (optw) {
-                       for (j = 0; j < optl; j += 4096) {
-                               ts->ts_map[i][j] = 1;
-                       }
-               }
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (munmap((void *)ts->ts_map[i], optl) == -1) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count += lm_optB;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-       char                    flags[5];
-
-       flags[0] = anon ? 'a' : '-';
-       flags[1] = optr ? 'r' : '-';
-       flags[2] = optw ? 'w' : '-';
-       flags[3] = opts ? 's' : '-';
-       flags[4] = 0;
-
-       (void) sprintf(result, "%8lld %5s", optl, flags);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/mutex.c b/tools/tests/libMicro/mutex.c
deleted file mode 100644 (file)
index 3c056af..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * mutex
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <sys/mman.h>
-
-#include "libmicro.h"
-
-static int                     optt = 0;
-static int                     optp = 0;
-static int                     opth = 0;
-static int                     opto = 0;
-
-pthread_mutex_t                        *lock;
-
-typedef struct {
-       int                     ts_once;
-       pthread_mutex_t         *ts_lock;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-t] (create dummy thread so we are multithreaded)\n"
-           "       [-p] (use inter-process mutex (not support everywhere))\n"
-           "       [-h usecs] (specify mutex hold time (default 0)\n"
-           "notes: measures uncontended pthread_mutex_[un,]lock\n");
-
-       (void) sprintf(lm_optstr, "tph:o:");
-
-       (void) sprintf(lm_header, "%8s", "holdtime");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'p':
-               optp = 1;
-               break;
-
-       case 't':
-               optt = 1;
-               break;
-
-       case 'h':
-               opth = sizetoint(optarg);
-               break;
-
-       case 'o':
-               opto = sizetoint(optarg);
-               break;
-
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-void *
-dummy(void *arg)
-{
-       (void) pause();
-       return (arg);
-}
-
-int
-benchmark_initrun()
-{
-       pthread_mutexattr_t     attr;
-       int errors = 0;
-
-       /*LINTED*/
-       lock = (pthread_mutex_t *)mmap(NULL,
-           getpagesize(),
-           PROT_READ | PROT_WRITE,
-           optp?(MAP_ANON | MAP_SHARED):MAP_ANON|MAP_PRIVATE,
-           -1, 0L) + opto;
-
-       if (lock == MAP_FAILED) {
-               errors++;
-       } else {
-               (void) pthread_mutexattr_init(&attr);
-               if (optp)
-                       (void) pthread_mutexattr_setpshared(&attr,
-                           PTHREAD_PROCESS_SHARED);
-
-               if (pthread_mutex_init(lock, &attr) != 0)
-                       errors++;
-       }
-
-       return (errors);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       int errors = 0;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-
-       if (optt) {
-               pthread_t               tid;
-
-
-
-               if (pthread_create(&tid, NULL, dummy, NULL) != 0) {
-                       errors++;
-               }
-       }
-
-       ts->ts_lock = lock;
-
-       return (errors);
-}
-
-void
-spinme(int usecs)
-{
-       long long s = getusecs();
-
-       while (getusecs() - s < usecs)
-               ;
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i ++) {
-
-               (void) pthread_mutex_lock(ts->ts_lock);
-               if (opth)
-                       spinme(opth);
-               (void) pthread_mutex_unlock(ts->ts_lock);
-
-       }
-
-       res->re_count = lm_optB;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8d", opth);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/nop.c b/tools/tests/libMicro/nop.c
deleted file mode 100644 (file)
index 815691f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * silly nop benchmark to test infrastructure
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "notes: measures nothing()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int     i;
-       int     nop();
-
-       for (i = 0; i < lm_optB; i++)
-               (void) nop(); /* do nothing but the call */
-
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/od_account_create.sh b/tools/tests/libMicro/od_account_create.sh
deleted file mode 100755 (executable)
index f087cdc..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/bash
-
-
-function sighandler {
-  echo 
-  echo "Interrupting account creation"
-  rm -f $TMPF
-  exit 1
-}
-
-trap sighandler INT TERM
-
-# Fixed parameters
-#
-NAME=`basename $0`
-COUNT=$1
-NODE=$2
-PREFIX="od_test_"
-GROUP_ID=1211  # A group everybody's in
-GROUP_ID2=1212 # A group nobody's in
-GROUP_NAME='od_test_group'
-UID_BASE=5000
-TMPF=/tmp/.${NAME}.$$
-
-usage () {
-  echo
-  echo "Usage: ${NAME} count nodename"
-  echo 
-  echo "   ie. ${NAME} 1000 /Local/Default"
-  echo
-  echo "       will create users 1000 users (from '${PREFIX}1' to '${PREFIX}1000')"
-  echo "       Default password is set to 'test'"
-  echo "       User ID starts from 5000"
-  echo "       Default group is '${GROUP_NAME}', Group ID 1211"
-  echo
-  echo "This tool assumes user 'diradmin' with password 'admin' for OD admin"
-  echo
-  exit 85 # WRONGARGS
-}
-
-if [ $# -ne 2 ]; then
-  usage
-fi
-
-# we don't need credentials if its a local node
-if [ $NODE != "/Local/Default" ]; then
-  OD_ADMIN="diradmin"
-  OD_PASS="admin"
-fi
-
-echo "Creating users ${PREFIX}1 to ${PREFIX}$COUNT"
-
-# check to see if od_test_group exist. if not, create one
-#
-result=`dscl $NODE -list Groups/${GROUP_NAME}1 2> /dev/null`
-if [ $? -ne 0 ]; then
-  echo "Group \"${GROUP_NAME}\" does not exist. Creating ${GROUP_NAME}"
-  if [ -n "$OD_ADMIN" ]; then
-    dseditgroup -q -o create -n $NODE -u $OD_ADMIN -P $OD_PASS -i ${GROUP_ID} ${GROUP_NAME}1
-    dseditgroup -q -o create -n $NODE -u $OD_ADMIN -P $OD_PASS -i ${GROUP_ID2} ${GROUP_NAME}2
-  else
-    dseditgroup -q -o create -n $NODE -i ${GROUP_ID} ${GROUP_NAME}1
-    dseditgroup -q -o create -n $NODE -i ${GROUP_ID2} ${GROUP_NAME}2
-  fi
-fi
-
-if [ $? -ne 0 ]; then
-       echo "Failed to create test_group"
-       exit 1
-fi
-
-# using dsimport is faster than using dscl
-i=1
-uid=$UID_BASE
-echo "Writing a temporary import file ..."
-while [ $i -le $COUNT ]
-do
-  result=`dscl $NODE -list Users/${PREFIX}${i} 2> /dev/null`
-  if [ $? -ne 0 ]; then 
-    # Uses standard template
-       # RecordName:Password:UniqueID:PrimaryGroupID:DistinguishedName:NFSHomeDirectory:UserShell
-       echo "${PREFIX}${i}:test:${uid}:1211:${PREFIX}${i}:/Users/${PREFIX}${i}:/bin/bash" >> $TMPF
-    printf "\r${PREFIX}${i} / ${COUNT}"
-  else
-    echo "account $PREFIX$i already exist. skipping"
-  fi
-  i=`expr $i + 1` 
-  uid=`expr $uid + 1` 
-done
-echo 
-
-# Now do the real work
-#
-if [[ -f $TMPF ]]; then
-  echo "Running dsimport to create users. Please be patient. This takes a while ..."
-  # assume if admin is provided that slapconfig exists
-  if [ -n "$OD_ADMIN" ]; then
-    if [[ -x "/usr/sbin/slapconfig" ]]; then
-      /usr/sbin/slapconfig -setfullsyncmode no
-      sleep 2
-    fi
-    /usr/bin/time dsimport $TMPF $NODE I --username $OD_ADMIN --password $OD_PASS --template StandardUser
-    sleep 2
-    if [[ -x "/usr/sbin/slapconfig" ]]; then
-      /usr/sbin/slapconfig -setfullsyncmode yes
-    fi
-  else
-    /usr/bin/time dsimport $TMPF $NODE I --template StandardUser
-    sleep 2
-  fi
-  
-  # and now delete the temp file
-  #
-  rm -f $TMPF
-else
-  echo "Nothing done. All users already exist"
-fi 
-
-echo Create a SACL group for libMicro
-# Create a sample SACL group
-dseditgroup -q -o create -r "libMicro ACL" com.apple.access_libMicro
-i=1
-while [ $i -le $COUNT ]; do
-       dseditgroup -q -o edit -a ${PREFIX}${i} -t user com.apple.access_libMicro 
-       i=`expr $i + 1` 
-done
-
-echo 'Finished'
-
diff --git a/tools/tests/libMicro/od_account_delete.sh b/tools/tests/libMicro/od_account_delete.sh
deleted file mode 100755 (executable)
index 45fb0e4..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/bash
-
-function sighandler {
-  echo 
-  echo "Interrupting account creation"
-  rm -f $TMPF
-  exit 2
-}
-
-trap sighandler INT TERM
-
-# Fixed parameters
-#
-NAME=`basename $0`
-COUNT=$1
-PREFIX="od_test_"
-GROUP_NAME='od_test_group'
-TMPF=/tmp/.${NAME}.$$
-NODE=$2
-
-usage () {
-  echo
-  echo "Usage: ${NAME} count nodename"
-  echo 
-  echo "   ie. ${NAME} 1000 /Local/Default"
-  echo
-  echo "       will delete ${GROUPNAME} and 1000 users "
-  echo "       from '${PREFIX}1' to '${PREFIX}1000'"
-  echo
-  echo "This tool assumes user 'diradmin' with password 'admin' for OD admin"
-  echo "when talking to anything other than /Local/Default"
-  exit 85 # WRONGARGS
-}
-
-if [ $# -ne 2 ]; then
-  usage
-fi
-
-# we don't need credentials if its a local node
-if [ $NODE != "/Local/Default" ]; then
-  OD_ADMIN="diradmin"
-  OD_PASS="admin"
-fi
-
-echo "Deleting users ${PREFIX}1 to ${PREFIX}$COUNT"
-
-# Using a script file and feed it into dscl is much faster than
-# calling dscl everytime.
-# 
-i=1
-echo "Writing a temporary script ..."
-if [ -n "$OD_ADMIN" ]; then
-  echo "auth $OD_ADMIN $OD_PASS" >> $TMPF
-fi
-
-while [ $i -le $COUNT ]
-do
-  result=`dscl $NODE -list Users/${PREFIX}${i} 2> /dev/null`
-  if [ $? -eq 0 ]; then
-    echo "delete Users/${PREFIX}${i}" >> $TMPF
-    printf "\r${PREFIX}${i} / ${COUNT}"
-  fi
-  i=`expr $i + 1` 
-done
-echo 
-
-echo "Deleting temporary test groups"
-if [ -n "$OD_ADMIN" ]; then
-  result=`dseditgroup -q -o delete -n $NODE -u $OD_ADMIN -P $OD_PASS ${GROUP_NAME}1 2>&1 /dev/null`
-  result=`dseditgroup -q -o delete -n $NODE -u $OD_ADMIN -P $OD_PASS ${GROUP_NAME}2 2>&1 /dev/null`
-else
-  result=`dseditgroup -q -o delete -n $NODE ${GROUP_NAME}1 2>&1 /dev/null`
-  result=`dseditgroup -q -o delete -n $NODE ${GROUP_NAME}2 2>&1 /dev/null`
-fi
-
-result=`dseditgroup -q -o delete com.apple.access_libMicro 2>&1 /dev/null`
-
-# Now do the real work
-#
-if [[ -f $TMPF ]]; then
-  echo "Running dscl to delete users. Please be patient. This takes a while ..."
-  if [[ -x /usr/sbin/slapconfig ]]; then
-    /usr/sbin/slapconfig -setfullsyncmode no
-  fi
-
-  /usr/bin/time dscl ${NODE} < $TMPF
-
-  if [[ -x /usr/sbin/slapconfig ]]; then
-    /usr/sbin/slapconfig -setfullsyncmode yes
-  fi
-fi
-
-# and now delete the temp file
-#
-rm -f $TMPF
-
-echo 'Finished'
-
diff --git a/tools/tests/libMicro/open.c b/tools/tests/libMicro/open.c
deleted file mode 100644 (file)
index 7cdcd76..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * benchmark open
- */
-
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_fds;
-} tsd_t;
-
-#define        DEFF                    "/dev/null"
-
-static char                    *optf = DEFF;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-open (default %s)]\n"
-           "notes: measures open()\n",
-           DEFF);
-
-       (void) sprintf(lm_optstr, "f:");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(lm_optB * lm_optT + 10);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_fds = (int *)malloc(lm_optB * sizeof (int));
-               if (ts->ts_fds == NULL) {
-                       errors++;
-               }
-               for (i = 0; i < lm_optB; i++) {
-                       ts->ts_fds[i] = -1;
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_fds[i] = open(optf, O_RDONLY);
-               if (ts->ts_fds[i] < 0) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) close(ts->ts_fds[i]);
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/pipe.c b/tools/tests/libMicro/pipe.c
deleted file mode 100644 (file)
index f1b3eb4..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       pid_t                   ts_child;
-       pthread_t               ts_thread;
-       int                     ts_in;
-       int                     ts_out;
-       int                     ts_in2;
-       int                     ts_out2;
-       int                     ts_lsn;
-       struct sockaddr_in      ts_add;
-} tsd_t;
-
-#define        FIRSTPORT               12345
-
-static char                    *modes[] = {"st", "mt", "mp", NULL};
-#define        MD_SINGLE               0
-#define        MD_MULTITHREAD          1
-#define        MD_MULTIPROCESS         2
-
-static char                    *xports[] = {"pipe", "fifo", "sock", "tcp",
-                                   NULL};
-#define        XP_PIPES                0
-#define        XP_FIFOS                1
-#define        XP_SOCKETPAIR           2
-#define        XP_LOCALTCP             3
-
-#define        DEFM                    MD_SINGLE
-#define        DEFS                    1024
-#define        DEFX                    XP_PIPES
-
-static int                     optm = DEFM;
-static size_t                  opts = DEFS;
-static int                     optx = DEFX;
-static void                    *rbuf = NULL;
-static void                    *wbuf = NULL;
-
-int readall(int s, void *buf, size_t len);
-void *loopback(void *arg);
-int prepare_pipes(tsd_t *tsd);
-int prepare_fifos(tsd_t *tsd);
-int cleanup_fifos(tsd_t *tsd);
-int prepare_socketpair(tsd_t *tsd);
-int prepare_localtcp(tsd_t *tsd);
-int prepare_localtcp_once(tsd_t *tsd);
-char *lookupa(int x, char *names[]);
-int lookup(char *x, char *names[]);
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "m:s:x:");
-
-       (void) sprintf(lm_usage,
-           "       [-m mode (st|mt|mp, default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-x transport (pipe|fifo|sock|tcp, default %s)]\n"
-           "notes: measures write()/read() across various transports\n",
-           lookupa(DEFM, modes), DEFS, lookupa(DEFX, xports));
-
-       (void) sprintf(lm_header, "%2s %4s", "md", "xprt");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       int                     x;
-
-       switch (opt) {
-       case 'm':
-               x = lookup(optarg, modes);
-               if (x == -1)
-                       return (-1);
-               optm = x;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       case 'x':
-               x = lookup(optarg, xports);
-               if (x == -1)
-                       return (-1);
-               optx = x;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       if (optx == XP_FIFOS) {
-               if (geteuid() != 0) {
-                       (void) printf("sorry, must be root to create fifos\n");
-                       exit(1);
-               }
-       }
-
-       (void) setfdlimit(4 * lm_optT + 10);
-
-       rbuf = malloc(opts);
-       wbuf = malloc(opts);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     result;
-       pid_t                   pid;
-
-       switch (optx) {
-       case XP_SOCKETPAIR:
-               result = prepare_socketpair(ts);
-               break;
-       case XP_LOCALTCP:
-               result = prepare_localtcp(ts);
-               break;
-       case XP_FIFOS:
-               result = prepare_fifos(ts);
-               break;
-       case XP_PIPES:
-       default:
-               result = prepare_pipes(ts);
-               break;
-       }
-       if (result == -1) {
-               return (1);
-       }
-
-       switch (optm) {
-       case MD_MULTITHREAD:
-               result = pthread_create(&ts->ts_thread, NULL, loopback, tsd);
-               if (result == -1) {
-                       return (1);
-               }
-               break;
-       case MD_MULTIPROCESS:
-               pid = fork();
-               switch (pid) {
-               case 0:
-                       (void) loopback(tsd);
-                       exit(0);
-                       break;
-               case -1:
-                       return (-1);
-               default:
-                       ts->ts_child = pid;
-                       break;
-               }
-               break;
-       case MD_SINGLE:
-       default:
-               break;
-       }
-
-       /* Prime the loopback */
-       if (write(ts->ts_out, wbuf, opts) != opts) {
-               return (1);
-       }
-       if (readall(ts->ts_in, rbuf, opts) != opts) {
-               return (1);
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     n;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (write(ts->ts_out, wbuf, opts) != opts) {
-                       res->re_errors++;
-                       continue;
-               }
-
-               n = readall(ts->ts_in, rbuf, opts);
-               if (n == -1) {
-                       res->re_errors++;
-                       continue;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       /* Terminate the loopback */
-       (void) write(ts->ts_out, wbuf, opts);
-       (void) readall(ts->ts_in, rbuf, opts);
-
-       switch (optm) {
-       case MD_MULTITHREAD:
-               (void) close(ts->ts_in2);
-               (void) close(ts->ts_out2);
-               (void) pthread_join(ts->ts_thread, NULL);
-               break;
-       case MD_MULTIPROCESS:
-               (void) close(ts->ts_in2);
-               (void) close(ts->ts_out2);
-               (void) waitpid(ts->ts_child, NULL, 0);
-               break;
-       case MD_SINGLE:
-       default:
-               break;
-       }
-
-       (void) close(ts->ts_in);
-       (void) close(ts->ts_out);
-
-       if (optx == XP_FIFOS) {
-               (void) cleanup_fifos(ts);
-       }
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%2s %4s",
-           lookupa(optm, modes), lookupa(optx, xports));
-
-       return (result);
-}
-
-int
-readall(int s, void *buf, size_t len)
-{
-       size_t                  n;
-       size_t                  total = 0;
-
-       for (;;) {
-               n = read(s, (void *)((long)buf + total), len - total);
-               if (n < 1) {
-                       return (-1);
-               }
-               total += n;
-               if (total >= len) {
-                       return (total);
-               }
-       }
-}
-
-void *
-loopback(void *arg)
-{
-       tsd_t                   *ts = (tsd_t *)arg;
-       int                     i, n, m;
-
-       /* Include priming and termination */
-       m = lm_optB + 2;
-
-       for (i = 0; i < m; i++) {
-               n = readall(ts->ts_in2, rbuf, opts);
-               if (n == -1) {
-                       break;
-               }
-               if (write(ts->ts_out2, wbuf, opts) != opts) {
-                       break;
-               }
-       }
-
-       return (NULL);
-}
-
-int
-prepare_localtcp_once(tsd_t *ts)
-{
-       int                     j;
-       int                     opt = 1;
-       struct hostent  *host;
-
-       j = FIRSTPORT;
-
-       ts->ts_lsn = socket(AF_INET, SOCK_STREAM, 0);
-       if (ts->ts_lsn == -1) {
-               return (-1);
-       }
-
-       if (setsockopt(ts->ts_lsn, SOL_SOCKET, SO_REUSEADDR,
-           &opt, sizeof (int)) == -1) {
-               return (-1);
-       }
-
-       if ((host = gethostbyname("localhost")) == NULL) {
-               return (-1);
-       }
-
-       for (;;) {
-               (void) memset(&ts->ts_add, 0,
-                   sizeof (struct sockaddr_in));
-               ts->ts_add.sin_family = AF_INET;
-               ts->ts_add.sin_port = htons(j++);
-               (void) memcpy(&ts->ts_add.sin_addr.s_addr,
-                   host->h_addr_list[0], sizeof (struct in_addr));
-
-               if (bind(ts->ts_lsn,
-                   (struct sockaddr *)&ts->ts_add,
-                   sizeof (struct sockaddr_in)) == 0) {
-                       break;
-               }
-
-               if (errno != EADDRINUSE) {
-                       return (-1);
-               }
-       }
-
-       if (listen(ts->ts_lsn, 5) == -1) {
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-prepare_localtcp(tsd_t *ts)
-{
-       int                     result;
-       struct sockaddr_in      addr;
-       int                     opt = 1;
-       socklen_t               size;
-
-       if (ts->ts_once++ == 0) {
-               if (prepare_localtcp_once(ts) == -1) {
-                       return (-1);
-               }
-       }
-
-       ts->ts_out = socket(AF_INET, SOCK_STREAM, 0);
-       if (ts->ts_out == -1) {
-               return (-1);
-       }
-
-       if (fcntl(ts->ts_out, F_SETFL, O_NDELAY) == -1) {
-               return (-1);
-       }
-
-       result = connect(ts->ts_out, (struct sockaddr *)&ts->ts_add,
-           sizeof (struct sockaddr_in));
-       if ((result == -1) && (errno != EINPROGRESS)) {
-               return (-1);
-       }
-
-       if (fcntl(ts->ts_out, F_SETFL, 0) == -1) {
-               return (-1);
-       }
-
-       size = sizeof (struct sockaddr);
-       result = accept(ts->ts_lsn, (struct sockaddr *)&addr, &size);
-       if (result == -1) {
-               return (-1);
-       }
-       ts->ts_out2 = result;
-
-       if (setsockopt(ts->ts_out, IPPROTO_TCP, TCP_NODELAY,
-           &opt, sizeof (int)) == -1) {
-               return (-1);
-       }
-
-       if (setsockopt(ts->ts_out2, IPPROTO_TCP, TCP_NODELAY,
-           &opt, sizeof (int)) == -1) {
-               return (-1);
-       }
-
-       if (optm == MD_SINGLE) {
-               ts->ts_in = ts->ts_out2;
-       } else {
-               ts->ts_in = ts->ts_out;
-               ts->ts_in2 = ts->ts_out2;
-       }
-
-       return (0);
-}
-
-int
-prepare_socketpair(tsd_t *ts)
-{
-       int                     s[2];
-
-       if (socketpair(PF_UNIX, SOCK_STREAM, 0, s) == -1) {
-               return (-1);
-       }
-
-       if (optm == MD_SINGLE) {
-               ts->ts_in = s[0];
-               ts->ts_out = s[1];
-       } else {
-               ts->ts_in = s[0];
-               ts->ts_out = s[0];
-               ts->ts_in2 = s[1];
-               ts->ts_out2 = s[1];
-       }
-
-       return (0);
-}
-
-int
-prepare_fifos(tsd_t *ts)
-{
-       char                    path[64];
-
-       (void) sprintf(path, "/private/tmp/pipe_%ld.%dA",
-           getpid(), pthread_self());
-       if (mknod(path, 0600, S_IFIFO) == -1) {
-               return (-1);
-       }
-
-       if (optm == MD_SINGLE) {
-               ts->ts_in = open(path, O_RDONLY);
-               ts->ts_out = open(path, O_WRONLY);
-       } else {
-               ts->ts_in = open(path, O_RDONLY);
-               ts->ts_out2 = open(path, O_WRONLY);
-
-               (void) sprintf(path, "/private/tmp/pipe_%ld.%dB",
-                   getpid(), pthread_self());
-               if (mknod(path, 0600, S_IFIFO) == -1) {
-                       return (-1);
-               }
-
-               ts->ts_in2 = open(path, O_RDONLY);
-               ts->ts_out = open(path, O_WRONLY);
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-cleanup_fifos(tsd_t *ts)
-{
-       char                    path[64];
-
-       (void) sprintf(path, "/private/tmp/pipe_%ld.%dA", getpid(), pthread_self());
-       (void) unlink(path);
-       (void) sprintf(path, "/private/tmp/pipe_%ld.%dB", getpid(), pthread_self());
-       (void) unlink(path);
-
-       return (0);
-}
-
-int
-prepare_pipes(tsd_t *ts)
-{
-       int                     p[2];
-
-       if (optm == MD_SINGLE) {
-               if (pipe(p) == -1) {
-                       return (-1);
-               }
-               ts->ts_in = p[0];
-               ts->ts_out = p[1];
-
-       } else {
-               if (pipe(p) == -1) {
-                       return (-1);
-               }
-               ts->ts_in = p[0];
-               ts->ts_out2 = p[1];
-
-               if (pipe(p) == -1) {
-                       return (-1);
-               }
-               ts->ts_in2 = p[0];
-               ts->ts_out = p[1];
-       }
-
-       return (0);
-}
-
-char *
-lookupa(int x, char *names[])
-{
-       int                     i = 0;
-
-       while (names[i] != NULL) {
-               if (x == i) {
-                       return (names[i]);
-               }
-               i++;
-       }
-       return (NULL);
-}
-
-int
-lookup(char *x, char *names[])
-{
-       int                     i = 0;
-
-       while (names[i] != NULL) {
-               if (strcmp(names[i], x) == 0) {
-                       return (i);
-               }
-               i++;
-       }
-       return (-1);
-}
diff --git a/tools/tests/libMicro/poll.c b/tools/tests/libMicro/poll.c
deleted file mode 100644 (file)
index 5ef1287..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#define        MAX(x, y)               ((x) > (y) ? (x) : (y))
-#define        MIN(x, y)               ((x) > (y) ? (y) : (x))
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <poll.h>
-#include <sys/socket.h>
-
-#include "libmicro.h"
-
-#define        DEFN                    256
-
-static int                     optn = DEFN;
-static int                     optr = 0;
-static int                     optw = 0;
-static int                     optx = 0;
-static int                     *fds;
-static int                     target = 0;
-
-typedef struct pollfd          pfd_t;
-
-typedef struct {
-       int                     ts_once;
-       pfd_t           *ts_pfds;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "n:r:w:x");
-
-       (void) sprintf(lm_usage,
-           "       [-n fds-per-thread (default %d)]\n"
-           "       [-r readable-fds (default 0)]\n"
-           "       [-w writeable-fds (default 0)]\n"
-           "       [-x] (start -r option with highest fd first; "
-           "default is lowest first)\n"
-           "notes: measures poll()\n",
-           DEFN);
-
-       (void) sprintf(lm_header, "%8s %5s", "nfds", "flags");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               optn = atoi(optarg);
-               break;
-       case 'r':
-               optr = atoi(optarg);
-               break;
-       case 'w':
-               optw = atoi(optarg);
-               break;
-       case 'x':
-               optx = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     i;
-       int                     j;
-       int                     pair[2];
-
-       if (optn % 2 != 0) {
-               (void) printf("ERROR: -n value must be even\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       if (optn < 0 || optr < 0 || optw < 0) {
-               (void) printf("ERROR: -n, -r and -w values must be > 0\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       if (optr > optn || optw > optn) {
-               (void) printf("ERROR: -r and -w values must be <= maxfd\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       fds = (int *)malloc(optn * sizeof (int));
-       if (fds == NULL) {
-               (void) printf("ERROR: malloc() failed\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       (void) setfdlimit(optn + 10);
-
-
-       for (i = 0; i < optn; i += 2) {
-               if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) == -1) {
-                       (void) printf("ERROR: socketpair() failed\n");
-                       return (-1);
-               }
-
-               fds[i] = MIN(pair[0], pair[1]);
-               fds[i+1] = MAX(pair[0], pair[1]);
-       }
-
-       if (optx) {
-               target = MIN(optr + optw, optn);
-               for (i = 0, j = optn - 1; i < optr; i++, j--) {
-                       (void) write(fds[j+1 - (2*(j%2))], "", 1);
-               }
-       } else {
-               target = MAX(optr, optw);
-               for (i = 0; i < optr; i++) {
-                       (void) write(fds[i+1 - (2*(i%2))], "", 1);
-               }
-       }
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_pfds = (pfd_t *)malloc(optn * sizeof (pfd_t));
-               if (ts->ts_pfds == NULL) {
-                       errors++;
-               }
-
-               for (i = 0; i < optn; i++) {
-                       ts->ts_pfds[i].fd = fds[i];
-                       ts->ts_pfds[i].events = POLLIN;
-               }
-
-               for (i = 0; i < optw; i++) {
-                       ts->ts_pfds[i].events |= POLLOUT;
-               }
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (poll(ts->ts_pfds, optn, 0) != target) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-       char                    flags[4];
-
-       flags[0] = optr ? 'r' : '-';
-       flags[1] = optw ? 'w' : '-';
-       flags[2] = optx ? 'x' : '-';
-       flags[3] = 0;
-
-       (void) sprintf(result, "%8d %5s", optn, flags);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/pread.c b/tools/tests/libMicro/pread.c
deleted file mode 100644 (file)
index 51e15d9..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFS                    1024
-
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-static int                     optw = 0;
-static int                     fd = -1;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "wf:s:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-read (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-w (write a byte to each page after read)]\n"
-           "notes: measures pread()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'w':
-               optw = getpagesize();
-               break;
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       fd = open(optf, O_RDONLY);
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     errors = 0;
-
-       if (ts->ts_buf == NULL) {
-               ts->ts_buf = malloc(opts);
-       }
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     j;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (pread(fd, ts->ts_buf, opts, 0) != opts) {
-                       res->re_errors++;
-               }
-               if (optw)  {
-                       for (j = 0; j < opts; j += optw)
-                               ts->ts_buf[j] = 0;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/pthread_create.c b/tools/tests/libMicro/pthread_create.c
deleted file mode 100644 (file)
index 340d35c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       pthread_t               *ts_threads;
-       pthread_attr_t          *ts_attr;
-       pthread_mutex_t         ts_lock;
-} tsd_t;
-
-static int                             opts = 0;
-
-int
-benchmark_init()
-{
-       lm_defN = "pthread";
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage,
-           "       [-s stacksize] (specify stacksize)\n"
-           "notes: measures pthread_create\n");
-
-       (void) sprintf(lm_optstr, "s:");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_initworker(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int errors = 0;
-
-       ts->ts_threads = calloc(lm_optB, sizeof (pthread_t));
-       (void) pthread_mutex_init(&ts->ts_lock, NULL);
-
-       if (opts) {
-               ts->ts_attr = malloc(sizeof (pthread_attr_t));
-               (void) pthread_attr_init(ts->ts_attr);
-               if ((errors = pthread_attr_setstacksize(ts->ts_attr, opts))
-                   != 0) {
-                       errno = errors;
-                       perror("pthread_attr_setstacksize");
-               }
-       } else
-               ts->ts_attr = NULL;
-
-       return (errors?1:0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       (void) pthread_mutex_lock(&ts->ts_lock);
-
-       return (0);
-}
-
-
-void *
-func(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       (void) pthread_mutex_lock(&ts->ts_lock);
-       (void) pthread_mutex_unlock(&ts->ts_lock);
-
-       return (tsd);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int error;
-
-       for (i = 0; i < lm_optB; i++) {
-               if ((error = pthread_create(ts->ts_threads + i,
-                   ts->ts_attr, func, tsd)) != 0) {
-                       errno = error;
-                       perror("pthread_create");
-                       ts->ts_threads[i] = 0;
-                       res->re_errors++;
-                       return (0);
-               }
-       }
-       res->re_count = lm_optB;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int i;
-       int errors = 0;
-
-       (void) pthread_mutex_unlock(&ts->ts_lock);
-
-       for (i = 0; i < lm_optB; i++)
-               if (ts->ts_threads[i] == 0 ||
-                   pthread_join(ts->ts_threads[i], NULL) < 0) {
-                       errors++;
-               }
-       return (errors);
-}
diff --git a/tools/tests/libMicro/pwrite.c b/tools/tests/libMicro/pwrite.c
deleted file mode 100644 (file)
index ab1374c..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-} tsd_t;
-
-#define        DEFF                    "/dev/null"
-#define        DEFS                    1024
-
-static int                     optc = 0;
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-static int                     fd = -1;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "cf:s:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-write (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-c ] (make sure buffer is in cache)\n"
-           "notes: measures pwrite()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'c':
-               optc++;
-               break;
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       fd = open(optf, O_WRONLY);
-       if (fd == -1) {
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       if (ts->ts_buf == NULL) {
-               ts->ts_buf = malloc(opts);
-
-               /*
-                * bring buf into cache if specified.
-                */
-
-               if (optc)
-                       for (i = 0; i < opts; i++)
-                               ts->ts_buf[i] = 0;
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (pwrite(fd, ts->ts_buf, opts, 0) != opts) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/read.c b/tools/tests/libMicro/read.c
deleted file mode 100644 (file)
index 32faf05..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-       int                     ts_fd;
-} tsd_t;
-
-#define        DEFF                    "/dev/zero"
-#define        DEFS                    1024
-
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-int                            optw = 0;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:s:w");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-read (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-w (store a byte to each page after read)]\n"
-           "notes: measures read()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       lm_defB = 1;
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'w':
-               optw = getpagesize();
-               break;
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (ts->ts_buf == NULL) {
-               ts->ts_buf = malloc(opts);
-               ts->ts_fd = open(optf, O_RDONLY);
-       }
-
-       (void) lseek(ts->ts_fd, 0, SEEK_SET);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     j;
-       for (i = 0; i < lm_optB; i++) {
-               if (read(ts->ts_fd, ts->ts_buf, opts) != opts) {
-                       res->re_errors++;
-               }
-               if (optw)
-                       for (j = 0; j < opts; j += optw)
-                               ts->ts_buf[j] = 0;
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/realpath.c b/tools/tests/libMicro/realpath.c
deleted file mode 100644 (file)
index 540ebf7..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/"
-#define        MAXPATHLEN              1024
-
-static char                    *optf = DEFF;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_optstr, "f:");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-f directory (default = %s)]\n"
-           "notes: measures realpath()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       char                    path[MAXPATHLEN];
-
-       for (i = 0; i < lm_optB; i++) {
-               if (realpath(optf, path) == NULL)
-                       res->re_errors++;
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/recurse.c b/tools/tests/libMicro/recurse.c
deleted file mode 100644 (file)
index 3237b46..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-#define        DEFD            100
-
-static int                     optd = DEFD;
-
-int recurse2(int x, int y, char *s);
-
-/*ARGSUSED*/
-int
-recurse1(int x, int y, char *s)
-{
-       char                    str[32];
-
-       if (x < y) {
-               return (recurse2(x + 1, y, str));
-       }
-
-       return (x);
-}
-
-int
-benchmark_init()
-{
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_optstr, "d:");
-
-       (void) sprintf(lm_usage,
-           "       [-d depth-limit (default = %d)]\n"
-           "notes: measures recursion performance\n",
-           DEFD);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'd':
-               optd = atoi(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) recurse1(0, optd, NULL);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/recurse2.c b/tools/tests/libMicro/recurse2.c
deleted file mode 100644 (file)
index 9f22890..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <string.h>
-
-int recurse1(int x, int y, char *s);
-
-/*ARGSUSED*/
-int
-recurse2(int x, int y, char *s)
-{
-       char                    str[32];
-
-       if (x < y) {
-               return (recurse1(x + 1, y, str));
-       }
-
-       return (x);
-}
diff --git a/tools/tests/libMicro/select.c b/tools/tests/libMicro/select.c
deleted file mode 100644 (file)
index 5edc37e..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#define        MAX(x, y)               ((x) > (y) ? (x) : (y))
-#define        MIN(x, y)               ((x) > (y) ? (y) : (x))
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-
-#include "libmicro.h"
-
-#define        DEFN                    256
-
-static int                     optn = DEFN;
-static int                     optr = 0;
-static int                     optw = 0;
-static int                     optx = 0;
-static int                     *fds;
-static fd_set                  iset;
-static fd_set                  oset;
-static int                     maxfd = 0;
-static int                     target = 0;
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_optstr, "n:r:w:x");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-n fds-per-thread (default %d)]\n"
-           "       [-r readable-fds (default 0)]\n"
-           "       [-w writeable-fds (default 0)]\n"
-           "       [-x] (start -r option with highest fd first; "
-           "default is lowest first)\n"
-           "notes: measures select()\n",
-           DEFN);
-
-       (void) sprintf(lm_header, "%8s %5s", "maxfd", "flags");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               optn = atoi(optarg);
-               break;
-       case 'r':
-               optr = atoi(optarg);
-               break;
-       case 'w':
-               optw = atoi(optarg);
-               break;
-       case 'x':
-               optx = 1;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       int                     i;
-       int                     j;
-       int                     pair[2];
-
-       if (optn % 2 != 0) {
-               (void) printf("ERROR: -n value must be even\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       if (optn < 0 || optr < 0 || optw < 0) {
-               (void) printf("ERROR: -n, -r and -w values must be > 0\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       if (optr > optn || optw > optn) {
-               (void) printf("ERROR: -r and -w values must be <= maxfd\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       fds = (int *)malloc(optn * sizeof (int));
-       if (fds == NULL) {
-               (void) printf("ERROR: malloc() failed\n");
-               optn = optr = optw = 0;
-               return (-1);
-       }
-
-       (void) setfdlimit(optn + 10);
-
-       target = optr + optw;
-
-       FD_ZERO(&iset);
-       FD_ZERO(&oset);
-
-       for (i = 0; i < optn; i += 2) {
-               if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) == -1) {
-                       (void) printf("ERROR: socketpair() failed\n");
-                       return (-1);
-               }
-
-               fds[i] = MIN(pair[0], pair[1]);
-               fds[i+1] = MAX(pair[0], pair[1]);
-               maxfd = fds[i+1] + 1;
-
-               if (maxfd > FD_SETSIZE) {
-                       (void) printf("WARNING: FD_SETSIZE is too small!\n");
-                       return (-1);
-               }
-
-               FD_SET(fds[i], &iset);
-               FD_SET(fds[i+1], &iset);
-       }
-
-       for (i = 0; i < optw; i++) {
-               FD_SET(fds[i], &oset);
-       }
-       if (optx) {
-               for (i = 0, j = optn - 1; i < optr; i++, j--) {
-                       (void) write(fds[j+1 - (2*(j%2))], "", 1);
-               }
-       } else {
-               for (i = 0; i < optr; i++) {
-                       (void) write(fds[i+1 - (2*(i%2))], "", 1);
-               }
-       }
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       fd_set                  set1;
-       fd_set                  set2;
-       fd_set          *my_iset = &set1;
-       fd_set          *my_oset = NULL;
-       struct timeval          tv = {0, 0};
-
-       if (optw) {
-               my_oset = &set2;
-       }
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) memcpy(&set1, &iset, sizeof (fd_set));
-               (void) memcpy(&set2, &oset, sizeof (fd_set));
-
-               if (select(maxfd, my_iset, my_oset, NULL, &tv) != target) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-       char                    flags[4];
-
-       flags[0] = optr ? 'r' : '-';
-       flags[1] = optw ? 'w' : '-';
-       flags[2] = optx ? 'x' : '-';
-       flags[3] = 0;
-
-       (void) sprintf(result, "%8d %5s", optn, flags);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/semop.c b/tools/tests/libMicro/semop.c
deleted file mode 100644 (file)
index 9953a79..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-
-#include "libmicro.h"
-
-
-typedef struct {
-       int     ts_semid;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage, "notes: measures semop()\n");
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if ((ts->ts_semid = semget(IPC_PRIVATE, 2, 0600)) == -1) {
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       (void) semctl(ts->ts_semid, 0, IPC_RMID);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       struct sembuf           s[1];
-
-       for (i = 0; i < lm_optB; i++) {
-               s[0].sem_num = 0;
-               s[0].sem_op  = 1;
-               s[0].sem_flg = 0;
-               if (semop(ts->ts_semid, s, 1) == -1) {
-                       res->re_errors++;
-               }
-               s[0].sem_num = 0;
-               s[0].sem_op  = -1;
-               s[0].sem_flg = 0;
-               if (semop(ts->ts_semid, s, 1) == -1) {
-                       res->re_errors++;
-               }
-       }
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/setcontext.c b/tools/tests/libMicro/setcontext.c
deleted file mode 100644 (file)
index dad2849..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ucontext.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-
-       (void) sprintf(lm_usage, "notes: measures setcontext()\n");
-
-       lm_tsdsize = 0;
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       volatile int            i;
-
-       ucontext_t uc;
-
-       i = 0;
-
-       (void) getcontext(&uc);
-
-       if (i++ < lm_optB)
-               (void) setcontext(&uc);
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/setsockopt.c b/tools/tests/libMicro/setsockopt.c
deleted file mode 100644 (file)
index c48672e..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int     ts_fd;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage, "setsockopt(TCP_NODELAY)\n");
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if ((ts->ts_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-               return (1);
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       (void) close(ts->ts_fd);
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     opt;
-
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i++) {
-               opt = 1 & i;
-               if (setsockopt(ts->ts_fd, IPPROTO_TCP, TCP_NODELAY,
-                   &opt, sizeof (int)) == -1) {
-                       res->re_errors ++;
-               }
-       }
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/sigaction.c b/tools/tests/libMicro/sigaction.c
deleted file mode 100644 (file)
index b0053b3..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "libmicro.h"
-
-#ifdef __sun
-static void
-nop()
-{
-}
-#else
-static void
-nop(int sig)
-{
-}
-#endif
-
-
-typedef struct {
-       struct sigaction ts_act;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_usage, "notes: measures sigaction()\n");
-
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-
-       tsd_t                   *ts = (tsd_t *)tsd;
-       ts->ts_act.sa_handler = nop;
-       ts->ts_act.sa_flags = 0;
-       (void) sigemptyset(&ts->ts_act.sa_mask);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       struct sigaction        oact;
-
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (sigaction(SIGUSR1, &ts->ts_act, &oact))
-                       res->re_errors++;
-       }
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/siglongjmp.c b/tools/tests/libMicro/siglongjmp.c
deleted file mode 100644 (file)
index 385530e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <setjmp.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       jmp_buf                 ts_env;
-} tsd_t;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage, "notes: measures siglongjmp()\n");
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-#if 1 /* Apple fix to longjmp/siglongjmp tests, see radar 7440118 */
-       volatile int i = 0;
-#else 
-       int i = 0;
-#endif /* end of Apple fix */
-
-       (void) sigsetjmp(ts->ts_env, 1);
-
-       if (i++ < lm_optB)
-               siglongjmp(ts->ts_env, 0);
-
-       res->re_count = lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/signal.c b/tools/tests/libMicro/signal.c
deleted file mode 100644 (file)
index 623aa08..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "libmicro.h"
-
-
-#ifdef __sun
-static void
-nop()
-{
-}
-#else
-static void
-nop(int sig)
-{
-}
-#endif
-
-int
-benchmark_init()
-{
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage, "notes: measures signal()\n");
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       struct sigaction act;
-
-       act.sa_handler = nop;
-       act.sa_flags = 0;
-
-       (void) sigemptyset(&act.sa_mask);
-       (void) sigaction(SIGUSR1, &act, NULL);
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       int                     pid;
-
-       pid = getpid();
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-               (void) kill(pid, SIGUSR1);
-       }
-       res->re_count += i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/sigprocmask.c b/tools/tests/libMicro/sigprocmask.c
deleted file mode 100644 (file)
index b94675e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage, "notes: measures sigprocmask()\n");
-
-       return (0);
-}
-
-int
-benchmark_initrun()
-{
-       sigset_t                iset;
-
-       (void) sigemptyset(&iset);
-       (void) sigprocmask(SIG_SETMASK, &iset, NULL);
-
-       return (0);
-}
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       sigset_t                set0, set1;
-
-       (void) sigemptyset(&set0);
-       (void) sigaddset(&set0, SIGTERM);
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) sigprocmask(SIG_SETMASK, &set0, &set1);
-               (void) sigprocmask(SIG_SETMASK, &set1, &set0);
-               (void) sigprocmask(SIG_SETMASK, &set0, &set1);
-               (void) sigprocmask(SIG_SETMASK, &set1, &set0);
-               (void) sigprocmask(SIG_SETMASK, &set0, &set1);
-               (void) sigprocmask(SIG_SETMASK, &set1, &set0);
-               (void) sigprocmask(SIG_SETMASK, &set0, &set1);
-               (void) sigprocmask(SIG_SETMASK, &set1, &set0);
-               (void) sigprocmask(SIG_SETMASK, &set0, &set1);
-               (void) sigprocmask(SIG_SETMASK, &set1, &set0);
-       }
-
-       res->re_count += i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/socket.c b/tools/tests/libMicro/socket.c
deleted file mode 100644 (file)
index 496966d..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_fds;
-} tsd_t;
-
-#define        DEFF            "PF_UNIX"
-
-static char                    *optf = DEFF;
-static int                     family;
-
-int
-lookup_family(char *name)
-{
-       if (strcmp("PF_UNIX", name) == 0) {
-               return (PF_UNIX);
-       } else if (strcmp("PF_INET", name) == 0) {
-               return (PF_INET);
-       } else if (strcmp("PF_INET6", name) == 0) {
-               return (PF_INET6);
-       }
-
-       return (-1);
-}
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-
-       (void) sprintf(lm_optstr, "f:n");
-
-       (void) sprintf(lm_usage,
-           "       [-f socket-family (default %s)]\n"
-           "notes: measures socket\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(lm_optB * lm_optT + 10);
-       family = lookup_family(optf);
-
-       return (0);
-}
-
-int
-benchmark_finirun()
-{
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_fds = (int *)malloc(lm_optB * sizeof (int));
-               if (ts->ts_fds == NULL) {
-                       return (1);
-               }
-               for (i = 0; i < lm_optB; i++) {
-                       ts->ts_fds[i] = -1;
-               }
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       for (i = 0; i < lm_optB; i++) {
-               ts->ts_fds[i] = socket(family, SOCK_STREAM, 0);
-               if (ts->ts_fds[i] == -1) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count += lm_optB;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) close(ts->ts_fds[i]);
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/socketpair.c b/tools/tests/libMicro/socketpair.c
deleted file mode 100644 (file)
index 59e7edb..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       int                     *ts_fds;
-} tsd_t;
-
-#define        DEFN            256
-
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       lm_defB = 256;
-
-       (void) sprintf(lm_usage,
-           "notes: measures socketpair\n");
-
-       return (0);
-}
-
-
-int
-benchmark_initrun()
-{
-       (void) setfdlimit(lm_optB * lm_optT + 10);
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_fds = (int *)malloc(lm_optB * sizeof (int));
-               if (ts->ts_fds == NULL) {
-                       return (1);
-               }
-               for (i = 0; i < lm_optB; i++) {
-                       ts->ts_fds[i] = -1;
-               }
-       }
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       res->re_count = 0;
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i += 2) {
-               if (socketpair(PF_UNIX, SOCK_STREAM, 0, &ts->ts_fds[i])
-                   == -1) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i / 2;
-
-       return (0);
-}
-
-int
-benchmark_finibatch(void *tsd)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       for (i = 0; i < lm_optB; i++) {
-               (void) close(ts->ts_fds[i]);
-       }
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/stat.c b/tools/tests/libMicro/stat.c
deleted file mode 100644 (file)
index cffccee..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "libmicro.h"
-
-#define        DEFF                    "/dev/null"
-static char                    *optf = DEFF;
-
-int
-benchmark_init()
-{
-
-       (void) sprintf(lm_optstr, "f:");
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-stat (default %s)]\n"
-           "notes: measures stat()\n",
-           DEFF);
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct stat             sbuf;
-
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (stat(optf, &sbuf) == -1)
-                       res->re_errors++;
-       }
-
-       res->re_count += lm_optB;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/strcasecmp.c b/tools/tests/libMicro/strcasecmp.c
deleted file mode 100644 (file)
index c57137b..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-
-static int unaligned = 0;
-static int opts = 100;
-
-typedef struct {
-       int     ts_once;
-       char    *ts_a;
-       char    *ts_b;
-       int     ts_fakegcc;
-} tsd_t;
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:n");
-
-       (void) sprintf(lm_usage,
-           "       [-s string size (default %d)]\n"
-           "       [-n causes unaligned cmp]\n"
-           "notes: measures strcasecmp()\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               unaligned = 1;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       static char *demo =
-           "The quick brown fox jumps over the lazy dog.";
-
-       if (ts->ts_once++ == 0) {
-               int l = strlen(demo);
-               int i;
-
-               ts->ts_a = malloc(opts + 1);
-               ts->ts_b = malloc(opts + 1 + unaligned);
-               ts->ts_b += unaligned;
-
-               for (i = 0; i < opts; i++) {
-                       ts->ts_a[i] = ts->ts_b[i] = demo[i%l];
-               }
-               ts->ts_a[opts] = 0;
-               ts->ts_b[opts] = 0;
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       char    *src    = ts->ts_a;
-       char    *src2   = ts->ts_b;
-       int     *sum    = &ts->ts_fakegcc;
-
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-               *sum += strcasecmp(src, src2);
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char     result[256];
-
-       if (unaligned == 0)
-               (void) sprintf(result, "%8d", opts);
-       else
-               (void) sprintf(result, "%8d <unaligned>", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/strchr.c b/tools/tests/libMicro/strchr.c
deleted file mode 100644 (file)
index 54c7477..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-static int unaligned = 0;
-static int opts = 100;
-
-typedef struct {
-       int     ts_once;
-       char    *ts_string;
-       char    *ts_fakegcc;
-} tsd_t;
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:n");
-
-       (void) sprintf(lm_usage,
-           "       [-s string size (default %d)]\n"
-           "       [-n causes unaligned strchr]\n"
-           "notes: measures strchr()\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               unaligned = 1;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t           *ts = (tsd_t *)tsd;
-
-       static char     *demo =
-           "The quick brown fox jumps over the lazy dog.";
-
-       if (ts->ts_once++ == 0) {
-               int l = strlen(demo);
-               int i;
-
-               ts->ts_string = malloc(opts + 1 + unaligned);
-               ts->ts_string += unaligned;
-
-
-               for (i = 0; i < opts; i++) {
-                       ts->ts_string[i] = demo[i%l];
-               }
-
-               ts->ts_string[opts] = 0;
-
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       char                    *src = ts->ts_string;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-               ts->ts_fakegcc = strchr(src, 'X');
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       if (unaligned == 0)
-               (void) sprintf(result, "%8d", opts);
-       else
-               (void) sprintf(result, "%8d <unaligned>", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/strcmp.c b/tools/tests/libMicro/strcmp.c
deleted file mode 100644 (file)
index c3c0da0..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-static int unaligned = 0;
-static int opts = 100;
-
-typedef struct {
-       int     ts_once;
-       char    *ts_a;
-       char    *ts_b;
-       int     ts_fakegcc;
-} tsd_t;
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:n");
-
-       (void) sprintf(lm_usage,
-           "       [-s string size (default %d)]\n"
-           "       [-n causes unaligned cmp]\n"
-           "notes: measures strcmp()\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               unaligned = 1;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       static char             *demo =
-           "The quick brown fox jumps over the lazy dog.";
-
-       if (ts->ts_once++ == 0) {
-               int l = strlen(demo);
-               int i;
-
-               ts->ts_a = malloc(opts + 1);
-               ts->ts_b = malloc(opts + 1 + unaligned);
-               ts->ts_b += unaligned;
-
-               for (i = 0; i < opts; i++) {
-                       ts->ts_a[i] = ts->ts_b[i] = demo[i%l];
-               }
-               ts->ts_a[opts] = 0;
-               ts->ts_b[opts] = 0;
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     *sum = &ts->ts_fakegcc;
-       char                    *src = ts->ts_a;
-       char                    *src2 = ts->ts_b;
-
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-               *sum += strcmp(src, src2);
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char     result[256];
-
-       if (unaligned == 0)
-               (void) sprintf(result, "%8d", opts);
-       else
-               (void) sprintf(result, "%8d <unaligned>", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/strcpy.c b/tools/tests/libMicro/strcpy.c
deleted file mode 100644 (file)
index 3a32353..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-static int unaligned = 0;
-static int opts = 100;
-
-typedef struct {
-       int     ts_once;
-       char    *ts_a;
-       char    *ts_b;
-} tsd_t;
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:n");
-
-       (void) sprintf(lm_usage,
-           "       [-s string size (default %d)]\n"
-           "       [-n causes unaligned cmp]\n"
-           "notes: measures strcpy()\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               unaligned = 1;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       static char             *demo =
-           "The quick brown fox jumps over the lazy dog.";
-
-       if (ts->ts_once++ == 0) {
-               int l = strlen(demo);
-               int i;
-
-               ts->ts_a = malloc(opts + 1);
-               ts->ts_b = malloc(opts + 1 + unaligned);
-               ts->ts_b += unaligned;
-
-               for (i = 0; i < opts; i++) {
-                       ts->ts_b[i] = demo[i%l];
-               }
-               ts->ts_b[opts] = 0;
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       char *src = ts->ts_a;
-       char *src2 = ts->ts_b;
-
-       res->re_errors = 0;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-               (void) strcpy(src, src2);
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char  result[256];
-
-       if (unaligned == 0)
-               (void) sprintf(result, "%8d", opts);
-       else
-               (void) sprintf(result, "%8d <unaligned>", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/strftime.c b/tools/tests/libMicro/strftime.c
deleted file mode 100644 (file)
index b056466..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "libmicro.h"
-
-#define        DEFF            "%c"
-#define        MAXSIZE                 80
-
-static char *optf = DEFF;
-
-typedef struct {
-       int             ts_once;
-       struct tm       ts_tm1;
-       struct tm       ts_tm2;
-} tsd_t;
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:");
-
-       (void) sprintf(lm_usage,
-           "       [-f format (default = \"%s\")]\n"
-           "notes: measures strftime()\n",
-           DEFF);
-
-       (void) sprintf(lm_header, "%8s", "format");
-
-       return (0);
-}
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-
-       case 'f':
-               optf = optarg;
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-
-char *
-benchmark_result()
-{
-       static char     result[256];
-
-       (void) sprintf(result, "%8s", optf);
-
-       return (result);
-}
-
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-
-       static time_t           clock1 = 0L;
-       static time_t           clock2 = 1L;
-
-       (void) localtime_r(&clock1, &ts->ts_tm1);
-       (void) localtime_r(&clock2, &ts->ts_tm2);
-
-       return (0);
-}
-
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       char                    s[MAXSIZE];
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm1);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm2);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm1);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm2);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm1);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm2);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm1);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm2);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm1);
-               (void) strftime(s, MAXSIZE, optf, &ts->ts_tm2);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/strlen.c b/tools/tests/libMicro/strlen.c
deleted file mode 100644 (file)
index bfcce12..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libmicro.h"
-
-static int unaligned = 0;
-static int opts = 100;
-
-typedef struct {
-       int     ts_once;
-       char    *ts_string;
-       int     ts_fakegcc;
-} tsd_t;
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "s:n");
-
-       (void) sprintf(lm_usage,
-           "       [-s string size (default %d)]\n"
-           "       [-n causes unaligned strlen]\n"
-           "notes: measures strlen()\n",
-           opts);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'n':
-               unaligned = 1;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       static char             *demo =
-           "The quick brown fox jumps over the lazy dog.";
-
-       if (ts->ts_once++ == 0) {
-               int l = strlen(demo);
-               int i;
-
-               ts->ts_string = malloc(opts + 1 + unaligned);
-               ts->ts_string += unaligned;
-
-
-               for (i = 0; i < opts; i++) {
-                       ts->ts_string[i] = demo[i%l];
-               }
-
-               ts->ts_string[opts] = 0;
-
-       }
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       tsd_t                   *ts = (tsd_t *)tsd;
-       char                    *src = ts->ts_string;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-               ts->ts_fakegcc += strlen(src);
-       }
-
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char     result[256];
-
-       if (unaligned == 0)
-               (void) sprintf(result, "%8d", opts);
-       else
-               (void) sprintf(result, "%8d <unaligned>", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/strtol.c b/tools/tests/libMicro/strtol.c
deleted file mode 100644 (file)
index 02f8abc..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       (void) sprintf(lm_usage, "note: measures strtol()");
-       lm_tsdsize = 0;
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) strtol("1", NULL, 10);
-               (void) strtol("11", NULL, 10);
-               (void) strtol("123", NULL, 10);
-               (void) strtol("1234", NULL, 10);
-               (void) strtol("12345", NULL, 10);
-               (void) strtol("123456", NULL, 10);
-               (void) strtol("1234567", NULL, 10);
-               (void) strtol("12345678", NULL, 10);
-               (void) strtol("123456789", NULL, 10);
-               (void) strtol("1234567890", NULL, 10);
-       }
-       res->re_count = i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/system.c b/tools/tests/libMicro/system.c
deleted file mode 100644 (file)
index d70db26..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "libmicro.h"
-
-#define        DEFB            10
-#define        DEFC            "A=$$"
-
-static char                    *optc = DEFC;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_optstr, "c:");
-
-       (void) sprintf(lm_usage,
-           "       [-c command (default %s)]\n"
-           "notes: measures system()\n",
-           DEFC);
-
-       (void) sprintf(lm_header, "%8s", "command");
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'c':
-               optc = optarg;
-               break;
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (system(optc) != 0) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = lm_optB;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char     result[256];
-
-       (void) sprintf(result, "%8s", optc);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/tattle.c b/tools/tests/libMicro/tattle.c
deleted file mode 100644 (file)
index 59520f8..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include <tattle.h>
-#include "libmicro.h"
-#include <math.h>
-
-
-#ifdef USE_RDTSC
-#ifdef __GNUC__
-#define        ENABLE_RDTSC 1
-#endif
-#endif
-
-/*
- * dummy so we can link w/ libmicro
- */
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       return (0);
-}
-
-static void
-cleanup(char *s)
-{
-       char *o = s;
-       char *e;
-
-       while (*s == ' ')
-               s++;
-
-       if (o != s)
-               (void) strcpy(o, s);
-
-       e = o;
-
-       while (*e != 0)
-               e++;
-
-       e--;
-
-       while (*e == ' ' && e > o)
-               *e-- = 0;
-
-}
-
-
-int
-main(int argc, char *argv[])
-{
-       int c;
-
-       if (strlen(compiler_version) > 30)
-               compiler_version[30] = 0;
-
-       cleanup(compiler_version);
-       cleanup(extra_compiler_flags);
-
-       while ((c = getopt(argc, argv, "vcfrsVTR")) != -1) {
-               switch (c) {
-               case 'V':
-                       (void) printf("%s\n", LIBMICRO_VERSION);
-                       break;
-               case 'v':
-                       (void) printf("%s\n", compiler_version);
-                       break;
-               case 'c':
-                       (void) printf("%s\n", CC);
-                       break;
-               case 'f':
-                       if (strlen(extra_compiler_flags) == 0)
-                               (void) printf("[none]\n");
-                       else
-                               (void) printf("%s\n", extra_compiler_flags);
-                       break;
-
-               case 's':
-                       (void) printf("%d\n", sizeof (long));
-                       break;
-
-               case 'r':
-
-                       (void) printf("%lld nsecs\n", get_nsecs_resolution());
-                       break;
-
-               case 'R':
-#ifdef ENABLE_RDTSC
-                       {
-                               struct timeval  s;
-                               struct timeval  f;
-                               long long       start_nsecs;
-                               long long       end_nsecs;
-                               long            elapsed_usecs;
-
-                               gettimeofday(&s, NULL);
-                               start_nsecs = rdtsc();
-                               for (;;) {
-                                       gettimeofday(&f, NULL);
-                                       elapsed_usecs = (f.tv_sec - s.tv_sec) *
-                                           1000000 + (f.tv_usec - s.tv_usec);
-                                       if (elapsed_usecs > 1000000)
-                                               break;
-                               }
-                               end_nsecs = rdtsc();
-                               (void) printf("LIBMICRO_HZ=%lld\n",
-                                   (long long)elapsed_usecs *
-                                   (end_nsecs - start_nsecs) / 1000000LL);
-                       }
-#else
-                       (void) printf("\n");
-#endif
-                       break;
-               }
-       }
-
-       exit(0);
-       return (0);
-}
diff --git a/tools/tests/libMicro/time.c b/tools/tests/libMicro/time.c
deleted file mode 100644 (file)
index aa46d49..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "notes: measures time()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-               (void) time(NULL);
-       }
-       res->re_count += i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/times.c b/tools/tests/libMicro/times.c
deleted file mode 100644 (file)
index 670af9b..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/times.h>
-#include <limits.h>
-
-#include "libmicro.h"
-
-int
-benchmark_init()
-{
-
-       lm_tsdsize = 0;
-
-       (void) sprintf(lm_usage,
-           "notes: measures times()\n");
-
-       return (0);
-}
-
-/*ARGSUSED*/
-int
-benchmark(void *tsd, result_t *res)
-{
-       int                     i;
-       struct tms              buf;
-
-       for (i = 0; i < lm_optB; i += 10) {
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-               (void) times(&buf);
-       }
-       res->re_count += i;
-
-       return (0);
-}
diff --git a/tools/tests/libMicro/wrapper.sh b/tools/tests/libMicro/wrapper.sh
deleted file mode 100755 (executable)
index 791643d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms
-# of the Common Development and Distribution License
-# (the "License").  You may not use this file except
-# in compliance with the License.
-#
-# You can obtain a copy of the license at
-# src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL
-# HEADER in each file and include the License file at
-# usr/src/OPENSOLARIS.LICENSE.  If applicable,
-# add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your
-# own identifying information: Portions Copyright [yyyy]
-# [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-
-BASENAME=`basename $0`
-DIRNAME=`dirname $0`
-ARCH=`uname -m`
-
-exec $DIRNAME/../bin-$ARCH/$BASENAME "$@"
diff --git a/tools/tests/libMicro/write.c b/tools/tests/libMicro/write.c
deleted file mode 100644 (file)
index 0780274..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifdef linux
-#define        _XOPEN_SOURCE 500
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#include "libmicro.h"
-
-typedef struct {
-       char                    *ts_buf;
-       int                     ts_fd;
-} tsd_t;
-
-#define        DEFF                    "/dev/null"
-#define        DEFS                    1024
-
-static int                     optc = 0;
-static char                    *optf = DEFF;
-static long long               opts = DEFS;
-static int                     optd;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "cdf:s:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-write (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-c ] (make sure buffer is in cache)\n"
-#ifdef __sun
-           "       [-d ] use directio"
-#endif
-           "notes: measures write()\n",
-           DEFF, DEFS);
-
-       (void) sprintf(lm_header, "%8s", "size");
-
-       lm_defB = 1;
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-
-       case 'd':
-               optd++;
-               break;
-       case 'c':
-               optc++;
-               break;
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoll(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       if (ts->ts_buf == NULL) {
-               ts->ts_buf = malloc(opts);
-               ts->ts_fd = open(optf, O_WRONLY);
-
-#ifdef __sun
-               if (optd)
-                       (void) directio(ts->ts_fd, DIRECTIO_ON);
-#endif
-               /*
-                * bring buf into cache if specified.
-                */
-
-               if (optc)
-                       for (i = 0; i < opts; i++)
-                               ts->ts_buf[i] = 0;
-       }
-
-       (void) lseek(ts->ts_fd, 0, SEEK_SET);
-
-       return (0);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (write(ts->ts_fd, ts->ts_buf, opts) != opts) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8lld", opts);
-
-       return (result);
-}
diff --git a/tools/tests/libMicro/writev.c b/tools/tests/libMicro/writev.c
deleted file mode 100644 (file)
index ac1bf2e..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms
- * of the Common Development and Distribution License
- * (the "License").  You may not use this file except
- * in compliance with the License.
- *
- * You can obtain a copy of the license at
- * src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing
- * permissions and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL
- * HEADER in each file and include the License file at
- * usr/src/OPENSOLARIS.LICENSE.  If applicable,
- * add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your
- * own identifying information: Portions Copyright [yyyy]
- * [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/uio.h>
-#include <limits.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-#ifndef IOV_MAX
-#define        IOV_MAX                 UIO_MAXIOV
-#endif
-
-#include "libmicro.h"
-
-typedef struct {
-       int                     ts_once;
-       struct iovec            *ts_iov;
-       int                     ts_fd;
-} tsd_t;
-
-#define        DEFF                    "/dev/null"
-#define        DEFS                    1024
-#define        DEFV                    10
-
-static char                    *optf = DEFF;
-static int                     opts = DEFS;
-static int                     optv = DEFV;
-
-int
-benchmark_init()
-{
-       lm_tsdsize = sizeof (tsd_t);
-
-       (void) sprintf(lm_optstr, "f:s:v:");
-
-       (void) sprintf(lm_usage,
-           "       [-f file-to-write (default %s)]\n"
-           "       [-s buffer-size (default %d)]\n"
-           "       [-v vector-size (default %d)]\n"
-           "notes: measures writev()\n"
-           "       IOV_MAX is %d\n"
-           "       SSIZE_MAX is %ld\n",
-           DEFF, DEFS, DEFV, IOV_MAX, SSIZE_MAX);
-
-       (void) sprintf(lm_header, "%8s %4s", "size", "vec");
-
-       lm_defB = 1;
-
-       return (0);
-}
-
-int
-benchmark_optswitch(int opt, char *optarg)
-{
-       switch (opt) {
-       case 'f':
-               optf = optarg;
-               break;
-       case 's':
-               opts = sizetoint(optarg);
-               break;
-       case 'v':
-               optv = atoi(optarg);
-               break;
-       default:
-               return (-1);
-       }
-       return (0);
-}
-
-int
-benchmark_initbatch(void *tsd)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-       int                     errors = 0;
-
-       if (ts->ts_once++ == 0) {
-               ts->ts_fd = open(optf, O_WRONLY);
-               if (ts->ts_fd == -1) {
-                       errors++;
-               }
-               ts->ts_iov = (struct iovec *)malloc(
-                   optv * sizeof (struct iovec));
-               for (i = 0; i < optv; i++) {
-                       ts->ts_iov[i].iov_base = malloc(opts);
-                       ts->ts_iov[i].iov_len = opts;
-               }
-       }
-
-       (void) lseek(ts->ts_fd, 0, SEEK_SET);
-
-       return (errors);
-}
-
-int
-benchmark(void *tsd, result_t *res)
-{
-       tsd_t                   *ts = (tsd_t *)tsd;
-       int                     i;
-
-       for (i = 0; i < lm_optB; i++) {
-               if (writev(ts->ts_fd, ts->ts_iov, optv) != opts * optv) {
-                       res->re_errors++;
-               }
-       }
-       res->re_count = i;
-
-       return (0);
-}
-
-char *
-benchmark_result()
-{
-       static char             result[256];
-
-       (void) sprintf(result, "%8d %4d", opts, optv);
-
-       return (result);
-}
diff --git a/tools/trace/bridgetime.lua b/tools/trace/bridgetime.lua
new file mode 100755 (executable)
index 0000000..cba2d52
--- /dev/null
@@ -0,0 +1,97 @@
+#!/usr/local/bin/luatrace -s
+
+trace_codename = function(codename, callback)
+       local debugid = trace.debugid(codename)
+       if debugid ~= 0 then
+               trace.single(debugid,callback)
+       else
+               printf("WARNING: Cannot locate debugid for '%s'\n", codename)
+       end
+end
+
+initial_timestamp = 0
+get_prefix = function(buf, char)
+       -- if initial_timestamp == 0 then
+               -- initial_timestamp = buf.timestamp
+       -- end
+       local secs = trace.convert_timestamp_to_nanoseconds(buf.timestamp - initial_timestamp) / 1000000000
+
+       return string.format("%s %6.9f %-30s",
+               char, secs, buf.debugname)
+end
+
+initial_arm_timestamp = 0
+format_timestamp_arm = function(ts)
+       local secs = trace.convert_timestamp_to_nanoseconds(ts - initial_arm_timestamp) / 1000000000
+       return string.format("%6.9f", secs);
+end
+
+initial_intel_timestamp = 0
+format_timestamp_intel = function(ts)
+       local secs = (ts - initial_intel_timestamp) / 1000000000
+       return string.format("%6.9f", secs);
+end
+
+format_timestamp_ns = function(ts)
+       local secs = (ts) / 1000000000
+       return string.format("%6.9f", secs);
+end
+
+trace_codename("MACH_CLOCK_BRIDGE_RESET_TS", function(buf)
+       local prefix = get_prefix(buf, "X")
+       local reason = "UNKNOWN";
+       if buf[3] == 1 then
+               reason = "RecvSentinel"
+       elseif buf[3] == 2 then
+               reason = "ResetTrue"
+       elseif buf[3] == 3 then
+               reason = "RateZero"
+       end
+       printf("%s %-15s ( %-10s %-10s ) ----------------------------------------\n",
+               prefix, reason, format_timestamp_arm(buf[1]), format_timestamp_intel(buf[2]))
+
+       -- initial_arm_timestamp = buf[1]
+       -- initial_intel_timestamp = buf[2]
+end)
+
+trace_codename("MACH_CLOCK_BRIDGE_TS_PARAMS", function(buf)
+       local prefix = get_prefix(buf, ">")
+
+       local rate
+       if darwin.uint64_to_double then
+               rate = darwin.uint64_to_double(buf[3])
+       else
+               rate = math.nan
+       end
+
+       printf("%s %30s( %-10s %-10s ) rate = %f\n",
+               prefix, "", format_timestamp_ns(buf[1]), format_timestamp_intel(buf[2]),
+               rate)
+end)
+
+trace_codename("MACH_CLOCK_BRIDGE_REMOTE_TIME", function(buf)
+       local prefix = get_prefix(buf, "-")
+
+       printf("%s ( %-10s %-10s ) @ %-20s\n",
+               prefix, format_timestamp_arm(buf[1]), format_timestamp_intel(buf[2]), format_timestamp_arm(buf[3]))
+end)
+
+trace_codename("MACH_CLOCK_BRIDGE_RCV_TS", function(buf)
+       local prefix = get_prefix(buf, "<")
+
+       if buf[2] == 0xfffffffffffffffe then
+               printf("%s ( %-10s  Sleep )\n",
+                       prefix, format_timestamp_arm(buf[1]), format_timestamp_intel(buf[2]))
+       elseif buf[2] == 0xfffffffffffffffd then
+               printf("%s ( %-10s Wake )\n",
+                       prefix, format_timestamp_arm(buf[1]), format_timestamp_intel(buf[2]))
+       elseif buf[2] == 0xfffffffffffffffc then
+               printf("%s ( %-10s Reset )\n",
+                       prefix, format_timestamp_arm(buf[1]), format_timestamp_intel(buf[2]))
+       else
+               printf("%s ( %-10s %-10s )\n",
+                       prefix, format_timestamp_arm(buf[1]), format_timestamp_intel(buf[2]))
+       end
+
+end)
+