Back to the Future: A Retroactive Study of Aspect Evolution in Operating System Code Sabine Hauert.
-
Upload
paul-daniel -
Category
Documents
-
view
215 -
download
0
Transcript of Back to the Future: A Retroactive Study of Aspect Evolution in Operating System Code Sabine Hauert.
Back to the Future: A Retroactive Study of Aspect
Evolution in Operating System Code
Back to the Future: A Retroactive Study of Aspect
Evolution in Operating System Code
Sabine HauertSabine Hauert
PlanPlan
Introduction FreeBSD and it’s evolutions Goals
Case studies Page Daemon Activation Prefetching Disk Quotas Blocking in Device Drivers
Summary Conclusions and discussion
Introduction FreeBSD and it’s evolutions Goals
Case studies Page Daemon Activation Prefetching Disk Quotas Blocking in Device Drivers
Summary Conclusions and discussion
IntroductionFreeBSD
IntroductionFreeBSD
What is FreeBSD? Free operating system x86, amd64 compatible Alpha/AXP, IA-64, PC-98 and
UltraSPARC® architectures. Derived from BSD, the version of UNIX ®
developed at the University of California, Berkeley.
What is FreeBSD? Free operating system x86, amd64 compatible Alpha/AXP, IA-64, PC-98 and
UltraSPARC® architectures. Derived from BSD, the version of UNIX ®
developed at the University of California, Berkeley.
IntroductionFreeBSD evolution
IntroductionFreeBSD evolution
V2
212,000 LOC
V3
357,000 LOC
V4
474,000 LOC
IntroductionFreeBSD evolution
IntroductionFreeBSD evolution
V2
212,000 LOC
V3
357,000 LOC
V4
474,000 LOC
Device Drivers:
- 581 new subdirectories
and files
- 100’000 LOC
IntroductionFreeBSD evolution
IntroductionFreeBSD evolution
V2
212,000 LOC
V3
357,000 LOC
V4
474,000 LOC
Page daemon activation sites:
- 50% less
IntroductionFreeBSD evolution
IntroductionFreeBSD evolution
V2
212,000 LOC
V3
357,000 LOC
V4
474,000 LOC
Blocking in Device Drivers:
- 50% more
IntroductionGoals
IntroductionGoals
Analyze the impact of evolution on an “aspect-oriented” implementation of the OS.
Compare with original version Localization Configurability Redundancy Modularity
Analyze the impact of evolution on an “aspect-oriented” implementation of the OS.
Compare with original version Localization Configurability Redundancy Modularity
Case Studies Page Daemon Activation
Case Studies Page Daemon Activation
Frees physical memory when the number available pages falls below some threshold. The daemon imposes overhead for determining which pages will be replaced and for writing them back to disk if necessary.
Speed is important Context specific Crosscuts operations that consume available pages
Frees physical memory when the number available pages falls below some threshold. The daemon imposes overhead for determining which pages will be replaced and for writing them back to disk if necessary.
Speed is important Context specific Crosscuts operations that consume available pages
Case Studies Page Daemon Activation: Where can it occur?
Case Studies Page Daemon Activation: Where can it occur?
Vm/
swap_pager.cgetpages() 1putpages() 3sync() 1io_done() 2
vm_fault.cadditional_pages() 1
vm_page.cunqueue() 1alloc() 5vm_wait() 1
usr/src/sys/
Kern/ vfs_bio.c
allocbuf()
Vm/
swap_pager.cgetpages()getpages()putpages()putpages()sync()sync()io_done()io_done()
vm_fault.cadditional_pages() 1
vm_page.cunqueue() 1alloc() 5vm_wait() 1
Vm/
swap_pager.cgetpages()getpages()putpages()putpages()sync()sync()io_done()io_done()
vm_fault.cadditional_pages() 1
vm_page.cunqueue() 1alloc() 3vm_wait() 1vm_await() 1+
aspect page_daemon_wakeup { pointcut unqueuing_available_pages(vm_page_t m): execution(void vm_page_unqueue(m)) && cflow(execution(void vm_page_activate(vm_page_t)) || execution(void vm_page_wire(vm_page_t)) || execution(void vm_page_unmanage(vm_page_t)) || execution(void vm_page_deactivate(vm_page_t, int)));
pointcut allocating_buffers(vm_object_t obj, vm_pindex_t pindex): execution(vm_page_t vm_page_lookup(obj, pindex)) && cflow(execution(int allocbuf(struct buf*, int))); around(vm_page_t m): unqueuing_available_pages(m) { int queue = m->queue; proceed(m); if (((queue - m->pc) == PQ_CACHE) && (pages_available() < vm_page_threshold())) pagedaemon_wakeup(); }
around(vm_object_t obj, vm_pindex_t pindex): allocating_buffers(obj, pindex) { vm_page_t m = proceed(obj, pindex); if ((m != NULL) && !(m->flags & PG_BUSY) && ((m->queue - m->pc) == PQ_CACHE) && (pages_available() < vfs_page_threshold())) pagedaemon_wakeup(); return m; }
… }
Locality
Functionality
Context
System-wide view
Case Studies Page Daemon Activation: Evolution
Case Studies Page Daemon Activation: Evolution
Changes are only made to the aspect Delete/add poincuts and advice Refactoring of threshold checks Adding little helper methods
Changes are only made to the aspect Delete/add poincuts and advice Refactoring of threshold checks Adding little helper methods
Case Studies Prefetching for mapped files
Case Studies Prefetching for mapped files
Prefetching is a heuristic designed to amortize costs by bringing in additional pages that may be required in the near future. VM suggests pages for prefetching File system decides crosscuts virtual memory and file systems,
coordinating high-level allocation and low-level de-allocation of prefetched pages.
Prefetching is a heuristic designed to amortize costs by bringing in additional pages that may be required in the near future. VM suggests pages for prefetching File system decides crosscuts virtual memory and file systems,
coordinating high-level allocation and low-level de-allocation of prefetched pages.
Case Studies Prefetching for mapped files: Where can it occur?
Case Studies Prefetching for mapped files: Where can it occur?
Vm/ vm_fault.c vm_fault() 3 additiona_pages() 1
gnu/ext2fs/ ext2_vnops.c ext2_getpages() 3
ufs/ufs/ ufs_readwrite.c ffs_getpages() 3
usr/src/sys/
ufs/ufs/ ufs_readwrite.c ffs_getpages() 4+ ffs_read() 1
ufs/ufs/ ufs_readwrite.c ffs_getpages() 3 - ffs_read() ffs_read()
aspect mapped_file_prefetching{
pointcut vm_fault_path(vm_map_t map): cflow(execution(int vm_fault(map,..)));
pointcut getpages_path(vm_map_t map, vm_object_t obj, vm_page_t* plist, int n, in fpage):
cflow(execution(int ffs_getpages(obj, plist, n, fpage) || execution(int vnode_leaf_pager_getpages(obj, plist,n,fpage)));
before(vm_map_t map, vm_object_t obj, vm_page_t* plist, int n, int fpage): execution(int vnode_pager_getpages(obj, plist, n, fpage)) && vm_fault_path(map) { …plan and allocate prefetched pages…}
after(vm_object_t obj, vm_page_t* plist, int n, int fpage, int valid): execution(valid check_valid(..)) && getpages_path(obj, plist, n, fpage) { …dealloc all prefetched pages…}
after(vm_object_t obj, vm_page_t* plist, int n, int fpage, struct transfer_args* trans_args): execution(int calc_range(trans_args)) && getpages_path(obj, plist, len, fpage) { …dealloc non contiguous pages… }…}
Case Studies Prefetching for mapped files: evolution
Case Studies Prefetching for mapped files: evolution
V2->V3: optimized implementation of sequential mode prefetching to FFS. Use of the file system read-path for sequential mode. Separation of the aspect in two aspects:
Normal sequential mode aspect Optimized sequential aspect
V3->V4: remove modifications in V3. Taking sequential aspect out of Makefile and
recombining both aspects in the normal mode aspect VS. Editing of code within FFS operations for a non-AO system.
V2->V3: optimized implementation of sequential mode prefetching to FFS. Use of the file system read-path for sequential mode. Separation of the aspect in two aspects:
Normal sequential mode aspect Optimized sequential aspect
V3->V4: remove modifications in V3. Taking sequential aspect out of Makefile and
recombining both aspects in the normal mode aspect VS. Editing of code within FFS operations for a non-AO system.
Case Studies Disk Quota
Case Studies Disk Quota
Designed to track disk utilization and enforce limits for all users and groups
Structure: set of low-level disk space related operations that are consistently monitoring/limiting all disk usage
crosscuts disk-consuming operations from multiple file systems
Designed to track disk utilization and enforce limits for all users and groups
Structure: set of low-level disk space related operations that are consistently monitoring/limiting all disk usage
crosscuts disk-consuming operations from multiple file systems
Case Studies Disk Quota: Where can it occur?
Case Studies Disk Quota: Where can it occur?
usr/src/sys/
ufs/ufs/ vnops.c 7 inode.c 3
gnu/ext2fs/ vfs.c 4 inode.c 2 alloc.c 3
ufs/ffs/ vfs.c 3 inode.c 2 alloc.c 5
ufs/ufs/ vnops.c 13 + inode.c 3 vfs.c 1 +
ufs/ffs/ vfs.c 3 inode.c 3+ alloc.c 5
gnu/ext2fs/ vfs.c 4 inode.c 2 alloc.c 3 vnops.c 8 +
ufs/ffs/ vfs.c 3 inode.c 3 alloc.c 5 balloc.c 1 +
ufs/ufs/ vnops.c 13 + inode.c 3 vfs.c 1 +
gnu/ext2fs/ vfs.c 4 inode.c 2 alloc.c 3 vnops.c 8 +
ufs/ffs/ vfs.c 3 inode.c 3 alloc.c 5 balloc.c 1 +
Case Studies Disk Quota
Case Studies Disk Quota
#ifdef QUOTA if (mp->mnt_flag & MNT_QUOTA) { int i; error = vflush(mp, 0, SKIPSYSTEM|flags); if (error) return (error); for (i = 0; i < MAXQUOTAS; i++) { if (ump->um_quotas[i] == NULLVP) continue; quotaoff(p, mp, i); } } #endif ... }
#if QUOTA int i; #endif ... #if QUOTA if (mp->mnt_flag & MNT_QUOTA) { if ((error = vflush(mp, 0, SKIPSYSTEM|flags))
!=0) return (error);
for (i = 0; i < MAXQUOTAS; i++) { if (ump->um_quotas[i] == NULLVP) continue;
quotaoff(p, mp, i); } }
#endif ... }
aspect disk_quota { pointcut flushfiles(register struct mount *mp, int flags, struct proc *p): execution(int ffs_flushfiles(mp, flags, p)) || execution(int ext2_flushfiles(mp, flags, p)); around(register struct mount *mp, int flags, struct proc *p): flushfiles(mp, flags, p) { register struct ufsmount *ump;
ump = VFSTOUFS(mp); if (mp->mnt_flag & MNT_QUOTA) { int i; int error = vflush(mp, NULLVP, SKIPSYSTEM|flags);
if (error) return (error); for (i = 0; i < MAXQUOTAS; i++) { if (ump->um_quotas[i] == NULLVP)
continue; quotaoff(p, mp, i); }}
return proceed(mp, flags, p); }
Case Studies Disk Quota: Evolution
Case Studies Disk Quota: Evolution
Adding pointcuts and advice is needed to incrementally extend its configuration to include new functionality. V2->V3: new feature for server which
automatically assigned the ownership of a new file to be that of the enclosing directory.
Adding pointcuts and advice is needed to incrementally extend its configuration to include new functionality. V2->V3: new feature for server which
automatically assigned the ownership of a new file to be that of the enclosing directory.
Case Studies Blocking in device drivers
Case Studies Blocking in device drivers
Explicitly surrender the CPU and block, allowing another process to run
Keep CPU busy while processes waits for device I/O
crosscuts all device-specific operations involved with I/O
Explicitly surrender the CPU and block, allowing another process to run
Keep CPU busy while processes waits for device I/O
crosscuts all device-specific operations involved with I/O
Case Studies Blocking: Where can it occur?
Case Studies Blocking: Where can it occur?
version LOC devices
(subdirs)
Calls to tsleep()
Tsleep() w/ no timeout
2 8400 7 5 2
3 46900 27 55 11
4 114800 69 110 22
Case Studies Blocking: tracking non-timeout tsleeps()
Case Studies Blocking: tracking non-timeout tsleeps()
aspect device_blocked_notimeout { pointcut block_in_device(void* ident, int priority, const char* wmesg, int timo): call(int tsleep(ident, priority, wmesg, timo)) && within(“/usr/src/sys/dev”);
before(void* ident, int priority, const char* wmesg, int timo): block_in_device(ident, priority, wmesg, timo) { if (timo == 0)
printf(“Blocking in device, no timeout: %s pid: %d\n”, wmesg, curproc->p_pid); }
}
Case Studies Disk Quota: Evolution
Case Studies Disk Quota: Evolution
No evolution needed! No evolution needed!
concern Major evolution Structural challenge
Original/aspect Benefits
Page daemon
wakeup
Revamping of code it crosscuts: VM and buffer cache
Multiple context specific thresholds
Scattered activation
/
Textually localized
Independent development & localized change
Prefetching for mapped files
Change in design of sequential mode
New subsystem interaction along execution paths
Internal to function
/
Explicit control flow
Explicit subsystem interaction & pluggability in makefile
Disk quota New functionality in code it crosscuts:
UFS,FFS,EXT2
Configurability
And sharing across file systems
#ifdefs w/ redundant code
/
Explicit sharing
Pointcut configurability
& reduced redundancy
Device blocking New device drivers added to the system
Consistency across rapidly growing diversity
Individualized devices /
Centralized assessment
Comprehensive coverage & further extensibility modularized
ConclusionConclusion
Changeability Textual locality => consistency
Configurability Modifying aspects Modifying makefile options
Redundancy Quota aspect example
Extensibility Device aspect
Changeability Textual locality => consistency
Configurability Modifying aspects Modifying makefile options
Redundancy Quota aspect example
Extensibility Device aspect
DiscussionDiscussion
What about the disadvantages? How biased is the analysis? How to define the limit between what
should be in an aspect and what shouldn’t: core functionality vs. non core functionality.
Can we know how a system will evolve?
What about the disadvantages? How biased is the analysis? How to define the limit between what
should be in an aspect and what shouldn’t: core functionality vs. non core functionality.
Can we know how a system will evolve?