text:
Central Connecticut senior Jamie Rademacher, volleyball, and junior Andrew Hill, men's cross country, were named Northeast Conference Fall Scholar-Athlete for their respective sport for the 2012 season. Both student-athletes excelled in competition during the fall season while maintaining the exceptional academic performance that they have exhibited throughout their careers.
In addition, 55 CCSU student-athletes were named to the NEC Academic Honor Roll for the fall season, including 13 Blue Devils that were also recognized on the Commissioner's Honor Roll.
Rademacher caps a stellar senior campaign with her selection as the women's volleyball scholar-athlete award winner. She was voted to the All-NEC second team after leading the NEC with a .361 hitting percentage this past fall. She also ranked among the NEC's top-10 in blocks (0.92/set) and finished third on the Blue Devils in kills (2.10/set).
A team captain for 2012, Rademacher was a three-time NEC Player of the Week and helped lead CCSU to a berth in the NEC Tournament. The tournament appearance was the 10th consecutive for the Blue Devil squad.
"I am thrilled that Jamie has received this wonderful recognition," head coach Linda Sagnelli said upon hearing of Rademacher's honor. "Jamie is such a great ambassador of our university and volleyball program, her work ethic and drive is what has helped her be so successful both in the classroom and on the court. We are all very proud of her."
In the classroom, the New Lenox, IL product registered a perfect 4.0 grade point average in the fall to boost her cumulative GPA to 3.91. Rademacher, a marketing major, has been an NEC Academic Honor Roll and Commissioner's Honor Roll member each year of her CCSU tenure.
In early November, Rademahcer was named a Capital One Academic All-District selection by CoSIDA, an honor that placed her among the top volleyball student-athletes in the region for both academics and athletics.
Hill becomes the latest Blue Devil to take home the men's cross country scholar-athlete award, joining former teammates Sam Alexander and Ry Sanderson.
According to head coach Eric Blake, "Andrew has been a great student-athlete the past three years. He is an extremely hard worker who leads by example and he works just as hard in the classroom as he does in practice and at meets." Blake added, "This has been a breakthrough year for him as an athlete. His individual success was a great contribution to our 2012 NEC Championship team."
This past October, Hill earned All-Conference honors as the Blue Devils claimed their fourth consecutive NEC Championship. He crossed the finish line in 25:42 for 11th place, finishing less than 40 seconds behind the lead runner and NEC Individual Champion, CCSU's Colby Delbene.
Hill kicked off his 2012 season taking first at the Quinnipiac Invitational, crossing the finish line in 27:40.2. He followed up the win with a 10th-place finish at the CCSU Mini Meet in a field of 76 competitors. Hill wrapped up his junior campaign with a 91st-place finish out of 238 runners at the NCAA Regionals.
In addition to serving as a valuable asset to the CCSU men's cross country squad on the course, the Colchester, CT native also leads the Blue Devils with a 3.77 grade point average as an education major with a concentration in mathematics.
The NEC Academic Honor Roll recognizes student-athletes that maintain a grade point average above a 3.20 on a 4.0 scale. CCSU's 55 student-athletes on the honor roll were spread across all six of the institution's fall sports. Leading the way was the CCSU women's soccer team with 18 student-athletes on the honor roll. Volleyball was represented on the honor roll by 10 student-athletes and men's soccer was close behind with nine members recognized. The CCSU football team and the women's cross country program both had seven individuals named to the honor roll and men's cross country had five student-athletes recognized.
To be named to the Commissioner's Honor Roll a student-athlete must maintain a 3.75 GPA through the completion of the most recent semester. Below are CCSU's 13 student-athletes that earned a place on the Commissioner's Honor Roll.
CCSU's Fall 2012 Commissioner's Honor Roll Selections
Andrew Hill • Men's Cross Country
Krisztina Dearborn • Women's Cross Country
Elizabeth Eberhardt • Women's Cross Country
Kaylene Sylvain • Women's Cross Country
Matthew Braddock • Football
Josef Abele • Men's Soccer
Stephen Walmsley • Men's Soccer
Benjamin Walsh • Men's Soccer
Reece Wilson • Men's Soccer
Amalia Ashley • Volleyball
Emily Cochran • Volleyball
Allyson Porter • Volleyball
Jamie Rademacher • Volleyball
Rademacher, Hill Named Scholar-Athlete
Central Connecticut senior Jamie Rademacher, volleyball, and junior Andrew Hill, men's cross country, were named Northeast Conference Fall Scholar-Athlete for their respective sport for the 2012 season. Both student-athletes excelled in competition during the fall season while maintaining the exceptional academic performance that they have exhibited throughout their careers.


text:
/ blobdiff
| inline |
side by side
vmrunkernel: allow -M for setting memory start
diff --git
--- a/
+++ b/
2. When Do We Really Leave "Process Context"?
3. Leaving the Kernel Stack
4. Preemption and Notification Issues
current_ctx and owning_proc
6. Locking!
7. TLB Coherency
8. Process Management
+9. On the Ordering of Messages
1. Reference Counting
current is a pointer to the proc that is currently loaded/running on any given
core. It is stored in the per_cpu_info struct, and set/managed by low-level
process code. It is necessary for the kernel to quickly figure out who is
-running on its co
e, especially when servicing interrupts and traps. current is
+running on its co
e, especially when servicing interrupts and traps. current is
protected by a refcnt.
+current does not say which process owns / will-run on a core. The per-cpu
+variable 'owning_proc' covers that. 'owning_proc' should be treated like
+'current' (aka, 'cur_proc') when it comes to reference counting. Like all
+refcnts, you can use it, but you can't consume it without atomically either
+upping the refcnt or passing the reference (clearing the variable storing the
+reference). Don't pass it to a function that will consume it and not return
+without upping it.
1.4 Reference Counting Rules:
+1 for existing.
protected by a refcnt.
+1 for current.
- current counts as someone using it (expressing interest in the core), but is
also a source of the pointer, so its a bit different. Note that all kref's
- are sources of a pointer. Technically, to even use 'current', we should kref
- it and pass it around as a proc. We don't for performance reasons. When we
- are running on a core that has current loaded, the ref is both for its usage
- as well as for being the current process.
+ are sources of a pointer. When we are running on a core that has current
+ loaded, the ref is both for its usage as well as for being the current
+ process.
- You have a reference from current and can use it without refcnting, but
anything that needs to eat a reference or store/use it needs an incref first.
To be clear, your reference is *NOT* edible. It protects the cr3, guarantees
stores or makes a copy of the reference.
Refcnting and especially decreffing gets tricky when there are functions that
MAY not return. proc_restartcore() does not return (it pops into userspace).
might not return, if the core it was called on will
pop into
used to not return, if the core it was called on would
pop into
userspace (if it was a _S, or if the core is part of the vcoremap for a _M).
+This doesn't happen anymore, since we have cur_ctx in the per-cpu info.
Functions that MAY not return will "eat" your reference *IF* they do not return.
This means that you must have a reference when you call them (like always), and
screw up, and semantically, if the function returns, then we may still have an
interest in p and should decref later.
The downside is that functions need to determine if they will return or not,
-which can be a pain (a linear time search when running an _M, for instance,
-which can suck if we are trying to use a broadcast/logical IPI).
+which can be a pain (for an out-of-date example: a linear time search when
+running an _M, for instance, which can suck if we are trying to use a
+broadcast/logical IPI).
As the caller, you usually won't know if the function will return or not, so you
need to provide a consumable reference. Current doesn't count. For example,
proc_run(pid2proc(55)) works, since pid2proc() increfs for you. But you cannot
proc_run(current), unless you incref current in advance. Incidentally,
proc_running current doesn't make a lot of sense.
-As another example, __proc_startcore() will take your reference and store it
-in current. Since it is used by both the __startcore and the interrupt return
-paths (proc_restartcore() now, formerly called proc_startcore()), we're
-currently going with the model of "caller makes sure there is a ref for
-current". Check its comments for details.
1.6 Runnable List:
Procs on the runnable list need to have a refcnt (other than the +1 for
had it implicitly be refcnt'd (the fact that it's on the list is enough, sort of
as if it was part of the +1 for existing), but that complicates things. For
instance, it is a source of a reference (for the scheduler) and you could not
proc_run() a process from the runnable list without worrying about increfing it
-before hand. Remember that proc_run() might consume your reference (which
-actually turns into a current reference, which is later destroyed by decref in
+before hand. This isn't true anymore, but the runnable lists are getting
+overhauled anyway. We'll see what works nicely.
1.7 Internal Details for Specific Functions:
: makes sure enough refcnts are in place for all places that wi
-install current. This also makes it easier on the system (one big incref(n),
-instead of n increfs of (1) from multiple cores). In the off chance current was
-already set for a core receiving the kernel message, __startcore will decref.
-Also note that while proc_run() consumes your reference, it's not actually
-decreffing, so there's no danger within proc_run() of the process dying /
-__proc_startcore(): assumes all references to p are sorted.
*p is already
-accounted for as if it was current on the core startcore runs on. (there is only
one refcnt for both *p and current, not 2 separate ones)
-proc_destroy(): it
might not return (if the calling core belongs to the
-process), so it may eat your reference and you must have an edible reference.
It is possible you called proc_destroy(current). The cleanup of the curren
-will be its own decref, so you need to have a usable/real reference (current
-doesn't count as an edible reference). So incref before doing that. Even if p
-== current, proc_destroy() can't tell if you sent it p (and had a reference) or
-current and didn't.
-proc_yield(): this never returns, so it eats your reference. It will also
decref when it abandon_core()s
/__proc_give_cores(): makes sure enough refcnts are in place for a
+places that will install owning_proc. This also makes it easier on the system
+(one big incref(n), instead of n increfs of (1) from multiple cores).
+__set_proc_current() is a helper that makes sure p is the cur_proc. It will
+incref if installing a new reference to p. If it removed an old proc, it will
+__proc_startcore(): assumes all references to p are sorted.
It will not
+return, and you should not pass it a reference you need to decref(). Passing
it 'owning_proc' works, since you don't want to decref owning_proc
+proc_destroy(): it
used to not return, and back then if your reference was
+from 'current', you needed to incref. Now that proc_destroy() returns, it
isn't a big deal. Just keep in mind that if you have a function that doesn'
+return, there's no way for the function to know if it's passed reference is
+edible. Even if p == current, proc_destroy() can't tell if you sent it p (and
+had a reference) or current and didn't.
+proc_yield(): when this doesn't return, it eats your reference. It will also
+decref twice. Once when it clears_owning_proc, and again when it calls
abandon_core() (which clears cur_proc)
abandon_core(): it was not given a reference, so it doesn't eat one. It will
decref when it unloads the cr3. Note that this is a potential performance
cores, after it knows all cores unloaded the cr3. This would be a good use of
the checklist (possibly with one cacheline per core). It would take a large
amount of memory for better scalability.
-1.8 Core Request:
-core_request() is run outside of the process code (for now), though it is fairly
-intricate. It's another function that might not return. Historically, there
-were a few reasons for it, but now only one is true (and may not be for long):
- 1: The process is moving from _S to _M so the return path to userspace won't
- happen (and sort of will on the new core / the other side), but that will
- happen when popping into userspace.
-For these reasons, core_request() needs to have an edible reference.
-Also, since core_request calls functions that might not return, there are cases
-where it will not be able to call abandon_core() and leave process context.
-This is an example of why we have the fallback case of leaving process context
-in proc_startcore(). See the section below about process context for more
-Eventually, core_request() will be split better, probably with the brutal logic
-in process.c that would call out some functions in resource.c that actually make
-1.9 Things I Could Have Done But Didn't And Why:
+1.8 Things I Could Have Done But Didn't And Why:
Q: Could we have the first reference (existence) mean it could be on the runnable
list or otherwise in the proc system (but not other subsystems)? In this case,
proc_run() won't need to eat a reference at all - it will just incref for every
current it will set up.
-A: No: if you pid2proc(), then proc_run() but never return, you have (and lose)
-an extra reference. We need proc_run() to eat the reference when it does not
-return. If you decref between pid2proc() and proc_run(), there's a (rare) race
-where the refcnt hits 0 by someone else trying to kill it. While proc_run()
-will check to see if someone else is trying to kill it, there's a slight chance
-that the struct will be reused and recreated. It'll probably never happen, but
-it could, and out of principle we shouldn't be referencing memory after it's
-been deallocated. Avoiding races like this is one of the reasons for our refcnt
+New A: Maybe, now that proc_run() returns.
+Old A: No: if you pid2proc(), then proc_run() but never return, you have (and
+lose) an extra reference. We need proc_run() to eat the reference when it
+does not return. If you decref between pid2proc() and proc_run(), there's a
+(rare) race where the refcnt hits 0 by someone else trying to kill it. While
+proc_run() will check to see if someone else is trying to kill it, there's a
+slight chance that the struct will be reused and recreated. It'll probably
+never happen, but it could, and out of principle we shouldn't be referencing
+memory after it's been deallocated. Avoiding races like this is one of the
+reasons for our refcnt discipline.
Could proc_run() always eat your reference, which would make it easier for
-its implementation?
(Moot) Could proc_run() always eat your reference, which would make it
easier for
its implementation?
A: Yeah, technically, but it'd be a pain, as mentioned above. You'd need to
reaquire a reference via pid2proc, and is rather easy to mess up.
Could we have made proc_destroy() take a flag, saying whether or not it was
-called on current and needed a decref instead of wasting an incref?
(Moot) Could we have made proc_destroy() take a flag, saying whether or not
it was
called on current and needed a decref instead of wasting an incref?
A: We could, but won't. This is one case where the external caller is the one
that knows the function needs to decref or not. But it breaks the convention a
bit, doesn't mirror proc_create() as well, and we need to pull in the cacheline
with the refcnt anyways. So for now, no.
-Q: Could we make __proc_give_cores() simply not return if an IPI is coming?
+Q: (Moot) Could we make __proc_give_cores() simply not return if an IPI is
A: I did this originally, and manually unlocked and __wait_for_ipi()d. Though
we'd then need to deal with it like that for all of the related functions, which
it to proc B.
If no process is running there, current == 0 and boot_cr3 is loaded, meaning no
process's context is loaded.
+All changes to cur_proc, owning_proc, and cur_ctx need to be done with
+interrupts disabled, since they change in interrupt handlers.
2.2 Here's how it is done now:
-We try to proactively leave, but have the ability to stay in context til
-__proc_startcore() to handle the corner cases (and to maybe cut down the TLB
-flushes later). To stop proactively leaving, just change abandon_core() to not
-do anything with current/cr3. You'll see weird things like processes that won't
-die until their old cores are reused. The reason we proactively leave context
-is to help with sanity for these issues, and also to avoid decref's in
+All code is capable of 'spamming' cur_proc (with interrupts disabled!). If it
+is 0, feel free to set it to whatever process you want. All code that
+requires current to be set will do so (like __proc_startcore()). The
+smp_idle() path will make sure current is clear when it halts. So long as you
+don't change other concurrent code's expectations, you're okay. What I mean
+by that is you don't clear cur_proc while in an interrupt handler. But if it
+is already 0, __startcore is allowed to set it to it's future proc (which is
+an optimization). Other code didn't have any expectations of it (it was 0).
+Likewise, kthread code when we sleep_on() doesn't have to keep cur_proc set.
+A kthread is somewhat an isolated block (codewise), and leaving current set
+when it is done is solely to avoid a TLB flush (at the cost of an incref).
+In general, we try to proactively leave process context, but have the ability
+to stay in context til __proc_startcore() to handle the corner cases (and to
+maybe cut down the TLB flushes later). To stop proactively leaving, just
+change abandon_core() to not do anything with current/cr3. You'll see weird
+things like processes that won't die until their old cores are reused. The
+reason we proactively leave context is to help with sanity for these issues,
+and also to avoid decref's in __startcore().
A couple other details: __startcore() sorts the extra increfs, and
__proc_startcore() sorts leaving the old context. Anytime a __startcore kernel
-message is sent, the sender increfs in advance for the current refcnt. If that
-was in error, __startcore decrefs. __proc_startcore(), which the last moment
-before we *must* have the cr3/current issues sorted, does the actual check if
-there was an old process there or not, while it handles the lcr3 (if necessary).
-In general, lcr3's ought to have refcnts near them, or else comments explaining
-why not.
+message is sent, the sender increfs in advance for the owning_proc refcnt. As
+an optimization, we can also incref to *attempt* to set current. If current
+was 0, we set it. If it was already something else, we failed and need to
+decref. __proc_startcore(), which the last moment before we *must* have the
+cr3/current issues sorted, does the actual check if there was an old process
+there or not, while it handles the lcr3 (if necessary). In general, lcr3's
+ought to have refcnts near them, or else comments explaining why not.
So we leave process context when told to do so (__death/abandon_core()) or if
another process is run there. The _M code is such that a proc will stay on its
There are two ways to deal with this. One (and the better one, I think) is to
check state, and determine if it should proceed or abort. This requires that
-all local-fate dependent calls always have enough state, meaning that any
-function that results in sending a directive to a vcore store enough info in
-the proc struct that a local call can determine if it should take action or
-abort. This might be sufficient. This works for death already, since you
-aren't supposed to do anything other than die (and restore any invariants
-first, handled in Section 3). We'll go with this way.
+all local-fate dependent calls always have enough state to do its job. In the
+past, this meant that any function that results in sending a directive to a
+vcore store enough info in the proc struct that a local call can determine if
+it should take action or abort. In the past, we used the vcore/pcoremap as a
+way to send info to the receiver about what vcore they are (or should be).
+Now, we store that info in pcpui (for '__startcore', we send it as a
+parameter. Either way, the general idea is still true: local calls can
+proceed when they are called, and not self-ipi'd to a nebulous later time.
The other way is to send the work (including the checks) in a self-ipi kernel
message. This will guarantee that the message is executed after any existing
for a proc until AFTER the preemption is completed.
4.2: Preempt-Served Flag
We want to be able to consider a pcore free once its owning proc has dealt
-with removing it (not necessarily taken from the vcoremap, but at least it is
-a done-deal that the core will go away and the messages are sent). This
-allows a scheduler-like function to easily take a core and then give it to
-someone else, without waiting for each vcore to respond, saying that the pcore
-is free/idle.
-Since we want to keep the pcore in the vcoremap, we need another signal to let
-a process know a message is already on its way. preempt_pending is a signal
-to userspace that the alarm was set, not that an actual message is on its way
-and that a vcore's fate is sealed. Since we can't use a pcore's presence in
-the vcoremap to determine that the core should be revoked, we have to check
-the "fate sealed"/preempt-served flag.
-It's a bit of a pain to have this flag, just to resolve this race in the
-kernel, though the local call would have to check the vcoremap anyway,
-incurring a cache miss if we go with using the vcoremap to signal the
-impending message.
+with removing it. This allows a scheduler-like function to easily take a core
+and then give it to someone else, without waiting for each vcore to respond,
+saying that the pcore is free/idle.
+We used to not unmap until we were in '__preempt' or '__death', and we needed
+a flag to tell yield-like calls that a message was already on the way and to
+not rely on the vcoremap. This is pretty fucked up for a number of reasons,
+so we changed that. But we still wanted to know when a preempt was in
+progress so that the kernel could avoid giving out the vcore until the preempt
+was complete.
+Here's the scenario: we send a '__startcore' to core 3 for VC5->PC3. Then we
+quickly send a '__preempt' to 3, and then a '__startcore' to core 4 (a
+different pcore) for VC5->PC4. Imagine all of this happens before the first
+'__startcore' gets processed (IRQ delay, fast ksched, whatever). We need to
+not run the second '__startcore' on pcore 4 before the preemption has saved
+all of the state of the VC5. So we spin on preempt_served (which may get
+renamed to preempt_in_progress). We need to do this in the sender, and not
+the receiver (not in the kmsg), because the kmsgs can't tell which one they
+are. Specifically, the first '__startcore' on core 3 runs the same code as
+the '__startcore' on core 4, working on the same vcore. Anything we tell VC5
+will be seen by both PC3 and PC4. We'd end up deadlocking on PC3 while it
+spins waiting for the preempt message that also needs to run on PC3.
The preempt_pending flag is actual a timestamp, with the expiration time of
the core at which the message will be sent. We could try to use that, but
assumptions about the vcore->pcore mapping and can result in multiple
instances of the same vcore on different pcores. Imagine a preempt message
sent to a pcore (after the alarm goes off), meanwhile that vcore/pcore yields
and the vcore reactivates somewhere else. There is a potential race on the
state: the new vcore is reading while the old is writing. This
state: the new vcore is reading while the old is writing. This
issue is sorted naturally: the vcore entry in the vcoremap isn't cleared until
the vcore/pcore is actually yielded/taken away, so the code looking for a free
vcoreid slot will not try to use it.
process is not running. Ultimately, the process wants to be notified on a
given vcore. Whenever we send an active notification, we set a flag in procdata
(notif_pending). If the vcore is offline, we don't bother sending the IPI/notif
message. The kernel will make sure it runs the notification handler (as well as
-restoring the
) the next time that vcore is restarted. Note that
+restoring the
) the next time that vcore is restarted. Note that
userspace can toggle this, so they can handle the notifications from a different
core if it likes, or they can independently send a notification.
Note we use notif_pending to detect if an IPI was missed while notifs were
-disabled (this is done in pop_ros_tf() by userspace). The overall meaning of
-notif_pending is that a vcore wants to be IPI'd. The IPI could be in-flight, or
-it could be missed. Since notification IPIs can be spurious, when we have
-potential races, we err on the side of sending. This happens when pop_ros_tf()
-notifies itself, and when the kernel starts a vcore in it's notif handler if it
-was preempted and notif was pending. In the latter case, the kernel will put
-the preempt_tf in the notif_tf, so userspace can restart that at its leisure.
+disabled (this is done in pop_user_ctx() by userspace). The overall meaning
+of notif_pending is that a vcore wants to be IPI'd. The IPI could be
+in-flight, or it could be missed. Since notification IPIs can be spurious,
+when we have potential races, we err on the side of sending. This happens
+when pop_user_ctx() notifies itself, and when the kernel makes sure to start a
+vcore in vcore context if a notif was pending. This was simplified a bit over
+the years by having uthreads always get saved into the uthread_ctx (formerly
+the notif_tf), instead of in the old preempt_tf (which is now the vcore_ctx).
If a vcore has a preempt_pending, we will still send the active notification
(IPI). The core ought to get a notification for the preemption anyway, so we
do is execute the notification handler and jump to userspace. Since there is
still an k_msg in the queue (and we self_ipi'd ourselves, it's part of how
k_msgs work), the IPI will fire and push us right back into the kernel to
execute the preemption, and the notif handler's context will be saved in the
(ready to go when the vcore gets started again).
(ready to go when the vcore gets started again).
We could try to just leave the notif_pending flag set and ignore the message,
but that would involve inspecting the queue for the preempt k_msg.
flexibility in schedule()-like functions (no need to wait to give the core
out), quicker dispatch latencies, less contention on shared structs (like the
idle-core-map), etc.
-Also, we don't remove the pcore from the vcoremap, even if it is being
-allocated to another core (the same pcore can exist in two vcoremaps, contrary
-to older statements). Taking the pcore from the vcoremap would mean some
-non-fate related local calls (sys_get_vcoreid()) will fail, since the vcoreid
-is gone! Additionally, we don't need a vcoreid in the k_msg (we would have if
-we could not use the vcore/pcoremappings). There should not be any issues
-with the new process sending messages to the pcore before the core is sorted,
-since k_msgs are delivered in order.
+This 'freeing' of the pcore is from the perspective of the kernel scheduler
+and the proc struct. Contrary to all previous announcements, vcores are
+unmapped from pcores when sending k_msgs (technically right after), while
+holding the lock. The pcore isn't actually not-running-the-proc until the
+kmsg completes and we abandon_core(). Previously, we used the vcoremap to
+communicate to other cores in a lock-free manner, but that was pretty shitty
+and now we just store the vcoreid in pcpu info.
Another tricky part is the seq_ctr used to signal userspace of changes to the
coremap or num_vcores (coremap_seqctr). While we may not even need this in the
future, we would like to have broadcast messaging of some sort (literally a
broadcast, like the IPIs, and if not that, then a communication tree of
-Given those desires, we want to make sure that no message we send needs
-details specific to a pcore (such as the vcoreid running on it, a history
-number, or anything like that). Thus no k_msg related to process management
-should have anything that cannot apply to the entire process. At this point,
-most just have a struct proc *. A pcore ought to be able to figure out what
-is happening based on the pcoremap, information in the struct proc, and in the
-preempt struct in procdata.
+In the past, (OLD INFO): given those desires, we wanted to make sure that no
+message we send needs details specific to a pcore (such as the vcoreid running
+on it, a history number, or anything like that). Thus no k_msg related to
+process management would have anything that cannot apply to the entire
+process. At this point, most just have a struct proc *. A pcore was be able
+to figure out what is happening based on the pcoremap, information in the
+struct proc, and in the preempt struct in procdata.
+In more recent revisions, the coremap no longer is meant to be used across
+kmsgs, so some messages ('__startcore') send the vcoreid. This means we can't
+easily broadcast the message. However, many broadcast mechanisms wouldn't
+handle '__startcore' naturally. For instance, logical IPIs need something
+already set in the LAPIC, or maybe need to be sent to a somewhat predetermined
+group (again, bits in the LAPIC). If we tried this for '__startcore', we
+could add something in to the messaging to carry these vcoreids. More likely,
+we'll have a broadcast tree. Keeping vcoreid (or any arg) next to whoever
+needs to receive the message is a very small amount of bookkeeping on a struct
+that already does bookkeeping.
4.10: Other Things We Thought of but Don't Like
We also considered using the transition stack as a signal that a process is in
a notification handler. The kernel can inspect the stack pointer to determine
this. It's possible, but unnecessary.
-5. current_tf
+Using the pcoremap as a way to pass info with kmsgs: it worked a little, but
+had some serious problems, as well as making life difficult. It had two
+purposes: help with local fate calls (yield) and allow broadcast messaging.
+The main issue is that it was using a global struct to pass info with
+messages, but it was based on the snapshot of state at the time the message
+was sent. When you send a bunch of messages, certain state may have changed
+between messages, and the old snapshot isn't there anymore by the time the
+message gets there. To avoid this, we went through some hoops and had some
+fragile code that would use other signals to avoid those scenarios where the
+global state change would send the wrong message. It was tough to understand,
+and not clear it was correct (hint: it wasn't). Here's an example (on one
+pcore): if we send a preempt and we then try to map that pcore to another
+vcore in the same process before the preempt call checks its pcoremap, we'll
+clobber the pcore->vcore mapping (used by startcore) and the preempt will
+think it is the new vcore, not the one it was when the message was sent.
+While this is a bit convoluted, I can imagine a ksched doing this, and
+perhaps with weird IRQ delays, the messages might get delayed enough for it to
+happen. I'd rather not have to have the ksched worry about this just because
+proc code was old and ghetto. Another reason we changed all of this was so
+that you could trust the vcoremap while holding the lock. Otherwise, it's
+actually non-trivial to know the state of a vcore (need to check a combination
+of preempt_served and is_mapped), and even if you do that, there are some
+complications with doing this in the ksched.
+5. current_ctx and owning_proc
-Originally, current_tf
s a per-core macro that returns a struct trapframe *
+Originally, current_tf
s a per-core macro that returns a struct trapframe *
that points back on the kernel stack to the user context that was running on
the given core when an interrupt or trap happened. Saving the reference to
the TF helps simplify code that needs to do something with the TF (like save
it and pop another TF). This way, we don't need to pass the context all over
the place, especially through code that might not care.
-Now, current_tf is more broadly defined as the user context that should be run
-when the kernel is ready to run a process. In the older case, it was when the
kernel tries to return to userspace from a trap/interrupt. Now,
be set by an IPI/KMSG (like '__startcore') so that when the kernel wants
-to idle, it will find a cur_tf that it needs to run, even though we never
+Then, current_tf was more broadly defined as the user context that should be
+run when the kernel is ready to run a process. In the older case, it was when
the kernel tries to return to userspace from a trap/interrupt.
be set by an IPI/KMSG (like '__startcore') so that when the kernel wants
+to idle, it will find a cur
_tf that it needs to run, even though we never
trapped in on that context in the first place.
-Process management KMSGs now simply modify cur_tf, as if we had interrupted a
-process. Instead of '__startcore' forcing the kernel to actually run the
-context, it will just mean we will eventually run it. In the meantime a
-'__notify' or a '__preempt' can come in, and they will apply to the cur_tf.
-This greatly simplifies process code and code calling process code (like the
-scheduler), since we no longer need to worry about whether or not we are
-getting a "stack killing" kernel message. Before this, code needed to care
-where it was running when managing _Ms.
-current_tf should go along with current. It's the current_tf of the current
-process. Withouth 'current', it has no meaning. This will probably change
-slightly, since kthreads care about 'current' but not about current_tf.
-It does not point to kernel trapframes, which is important when we receive an
-interrupt in the kernel. At one point, we were (hypothetically) clobbering the
-reference to the user trapframe, and were unable to recover. We can get away
-with this because the kernel always returns to its previous context from a
-nested handler (via iret on x86).
-In the future, we may need to save kernel contexts and may not always return via
-iret. At which point, if the code path is deep enough that we don't want to
-carry the TF pointer, we may revisit this. Until then, current_tf is just for
-userspace contexts, and is simply stored in per_cpu_info.
+Finally, current_tf was changed to current_ctx, and instead of tracking a
+struct trapframe (equivalent to a hw_trapframe), it now tracked a struct
+user_context, which could be either a HW or a SW trapframe.
+Further, we now have 'owning_proc', which tells the kernel which process
+should be run. 'owning_proc' is a bigger deal than 'current_ctx', and it is
+what tells us to run cur_ctx.
+Process management KMSGs now simply modify 'owning_proc' and cur_ctx, as if we
+had interrupted a process. Instead of '__startcore' forcing the kernel to
+actually run the process and trapframe, it will just mean we will eventually
+run it. In the meantime a '__notify' or a '__preempt' can come in, and they
+will apply to the owning_proc/cur_ctx. This greatly simplifies process code
+and code calling process code (like the scheduler), since we no longer need to
+worry about whether or not we are getting a "stack killing" kernel message.
+Before this, code needed to care where it was running when managing _Ms.
+Note that neither 'current_ctx' nor 'owning_proc' rely on 'current'/'cur_proc'.
+'current' is just what process context we're in, not what process (and which
+trapframe) we will eventually run.
+cur_ctx does not point to kernel trapframes, which is important when we
+receive an interrupt in the kernel. At one point, we were (hypothetically)
+clobbering the reference to the user trapframe, and were unable to recover.
+We can get away with this because the kernel always returns to its previous
+context from a nested handler (via iret on x86).
+In the future, we may need to save kernel contexts and may not always return
+via iret. At which point, if the code path is deep enough that we don't want
+to carry the TF pointer, we may revisit this. Until then, current_ctx is just
+for userspace contexts, and is simply stored in per_cpu_info.
+Brief note from the future (months after this paragraph was written): cur_ctx
+has two aspects/jobs:
+1) tell the kernel what we should do (trap, fault, sysc, etc), how we came
+into the kernel (the fact that it is a user tf), which is why we copy-out
+early on
+2) be a vehicle for us to restart the process/vcore
+We've been focusing on the latter case a lot, since that is what gets
+removed when preempted, changed during a notify, created during a startcore,
+etc. Don't forget it was also an instruction of sorts. The former case is
+always true throughout the life of the syscall. The latter only happens to be
+true throughout the life of a *non-blocking* trap since preempts are routine
+KMSGs. But if we block in a syscall, the cur_ctx is no longer the TF we came
+in on (and possibly the one we are asked to operate on), and that old cur_ctx
+has probably restarted.
+(Note that cur_ctx is a pointer, and syscalls/traps actually operate on the TF
+they came in on regardless of what happens to cur_ctx or pcpui->actual_tf.)
6. Locking!
on), and then that vcore gets granted in the next round of vcore_requests().
The preemption recovery handlers will need to deal with concurrent handlers
and the vcore itself starting back up.
+9. On the Ordering of Messages and Bugs with Old State
+This is a sordid tale involving message ordering, message delivery times, and
+finding out (sometimes too late) that the state you expected is gone and
+having to deal with that error.
+A few design issues:
+- being able to send messages and have them execute in the order they are
+ sent
+- having message handlers resolve issues with global state. Some need to know
+ the correct 'world view', and others need to know what was the state at the
+ time they were sent.
+- realizing syscalls, traps, faults, and any non-IRQ entry into the kernel is
+ really a message.
+Process management messages have alternated from ROUTINE to IMMEDIATE and now
+back to ROUTINE. These messages include such family favorites as
+'__startcore', '__preempt', etc. Meanwhile, syscalls were coming in that
+needed to know about the core and the process's state (specifically, yield,
+change_to, and get_vcoreid). Finally, we wanted to avoid locking, esp in
+KMSGs handlers (imagine all cores grabbing the lock to check the vcoremap or
+Incidentally, events were being delivered concurretly to vcores, though that
+actually didn't matter much (check out async_events.txt for more on that).
+9.1: Design Guidelines
+Initially, we wanted to keep broadcast messaging available as an option. As
+noted elsewhere, we can't really do this well for startcore, since most
+hardware broadcast options need some initial per-core setup, and any sort of
+broadcast tree we make should be able to handle a small message. Anyway, this
+desire in the early code to keep all messages identical lead to a few
+Another objective of the kernel messaging was to avoid having the message
+handlers grab any locks, especially the same lock (the proc lock is used to
+protect the vcore map, for instance).
+Later on, a few needs popped up that motivated the changes discussed below:
+- Being able to find out which proc/vcore was on a pcore
+- Not having syscalls/traps require crazy logic if the carpet was pulled out
+ from under them.
+- Having proc management calls return. This one was sorted out by making all
+ kmsg handlers return. It would be a nightmare making a ksched without this.
+9.2: Looking at Old State: a New Bug for an Old Problem
+We've always had issues with syscalls coming in and already had the fate of a
+core determined. This is referred to in a few places as "predetermined fate"
+vs "local state". A remote lock holder (ksched) already determined a core
+should be unmapped and sent a message. Only later does some call like
+proc_yield() realize its core is already *unmapped*. (I use that term poorly
+here). This sort of code had to realize it was working on an old version of
+state and just abort. This was usually safe, though looking at the vcoremap
+was a bad idea. Initially, we used preempt_served as the signal, which was
+okay. Around 12b06586 yield started to use the vcoremap, which turned out to
+be wrong.
+A similar issue happens for the vcore messages (startcore, preempt, etc). The
+way startcore used to work was that it would only know what pcore it was on,
+and then look into the vcoremap to figure out what vcoreid it should be
+running. This was to keep broadcast messaging available as an option. The
+problem with it is that the vcoremap may have changed between when the
+messages were sent and when they were executed. Imagine a startcore followed
+by a preempt, afterwhich the vcore was unmapped. Well, to get around that, we
+had the unmapping happen in the preempt or death handlers. Yikes! This was
+the case back in the early days of ROS. This meant the vcoremap wasn't
+actually representative of the decisions the ksched made - we also needed to
+look at the state we'd have after all outstanding messages executed. And this
+would differ from the vcore lists (which were correct for a lock holder).
+This was managable for a little while, until I tried to conclusively know who
+owned a particular pcore. This came up while making a provisioning scheduler.
+Given a pcore, tell me which process/vcore (if any) were on it. It was rather
+tough. Getting the proc wasn't too hard, but knowing which vcore was a little
+tougher. (Note the ksched doesn't care about which vcore is running, and the
+process can change vcores on a pcore at will). But once you start looking at
+the process, you can't tell which vcore a certain pcore has. The vcoremap may
+be wrong, since a preempt is already on the way. You would have had to scan
+the vcore lists to see if the proc code thought that vcore was online or not
+(which would mean there had been no preempts). This is the pain I was talking
+about back around commit 5343a74e0.
+So I changed things so that the vcoremap was always correct for lock holders,
+and used pcpui to track owning_vcoreid (for preempt/notify), and used an extra
+KMSG variable to tell startcore which vcoreid it should use. In doing so, we
+(re)created the issue that the delayed unmapping dealt with: the vcoremap
+would represent *now*, and not the vcoremap of when the messages were first
+sent. However, this had little to do with the KMSGs, which I was originally
+worried about. No one was looking at the vcoremap without the lock, so the
+KMSGs were okay, but remember: syscalls are like messages too. They needed to
+figure out what vcore they were on, i.e. what vcore userspace was making
+requests on (viewing a trap/fault as a type of request).
+Now the problem was that we were using the vcoremap to figure out which vcore
+we were supposed to be. When a syscall finally ran, the vcoremap could be
+completely wrong, and with immediate KMSGs (discussed below), the pcpui was
+already changed! We dealt with the problem for KMSGs, but not syscalls, and
+basically reintroduced the bug of looking at current state and thinking it
+represented the state from when the 'message' was sent (when we trapped into
+the kernel, for a syscall/exception).
+9.3: Message Delivery, Circular Waiting, and Having the Carpet Pulled Out
+In-order message delivery was what drove me to build the kernel messaging
+system in the first place. It provides in-order messages to a particular
+pcore. This was enough for a few scenarios, such as preempts racing ahead of
+startcores, or deaths racing a head of preempts, etc. However, I also wanted
+an ordering of messages related to a particular vcore, and this wasn't
+apparent early on.
+The issue first popped up with a startcore coming quickly on the heals of a
+preempt for the same VC, but on different PCs. The startcore cannot proceed
+until the preempt saved the TF into the VCPD. The old way of dealing with
+this was to spin in '__map_vcore()'. This was problematic, since it meant we
+were spinning while holding a lock, and resulted in some minor bugs and issues
+with lock ordering and IRQ disabling (couldn't disable IRQs and then try to
+grab the lock, since the lock holder could have sent you a message and is
+waiting for you to handle the IRQ/IMMED KMSG). However, it was doable. But
+what wasn't doable was to have the KMSGs be ROUTINE. Any syscalls that tried
+to grab the proc lock (lots of them) would deadlock, since the lock holder was
+waiting on us to handle the preempt (same circular waiting issue as above).
+This was fine, albeit subpar, until a new issue showed up. Sending IMMED
+KMSGs worked fine if we were coming from userspace already, but if we were in
+the kernel, those messages would run immediately (hence the name), just like
+an IRQ handler, and could confuse syscalls that touched cur_ctx/pcpui. If a
+preempt came in during a syscall, the process/vcore could be changed before
+the syscall took place. Some syscalls could handle this, albeit poorly.
+sys_proc_yield() and sys_change_vcore() delicately tried to detect if they
+were still mapped or not and use that to determine if a preemption happened.
+As mentioned above, looking at the vcoremap only tells you what is currently
+happening, and not what happened in the past. Specifically, it doesn't tell
+you the state of the mapping when a particular core trapped into the kernel
+for a syscall (referred to as when the 'message' was sent up above). Imagine
+sys_get_vcoreid(): you trap in, then immediately get preempted, then startcore
+for the same process but a different vcoreid. The syscall would return with
+the vcoreid of the new vcore, since it cannot tell there was a change. The
+async syscall would complete and we'd have a wrong answer. While this never
+happened to me, I had a similar issue while debugging some other bugs (I'd get
+a vcoreid of 0xdeadbeef, for instance, which was the old poison value for an
+unmapped vcoreid). There are a bunch of other scenarios that trigger similar
+disasters, and they are very hard to avoid.
+One way out of this was a per-core history counter, that changed whenever we
+changed cur_ctx. Then when we trapped in for a syscall, we could save the
+value, enable_irqs(), and go about our business. Later on, we'd have to
+disable_irqs() and compare the counters. If they were different, we'd have to
+bail out some how. This could have worked for change_to and yield, and some
+others. But any syscall that wanted to operate on cur_ctx in some way would
+fail (imagine a hypothetical sys_change_stack_pointer()). The context that
+trapped has already returned on another core. I guess we could just fail that
+syscall, though it seems a little silly to not be able to do that.
+The previous example was a bit contrived, but lets also remember that it isn't
+just syscalls: all exceptions have the same issue. Faults might be fixable,
+since if you restart a faulting context, it will start on the faulting
+instruction. However all traps (like syscall) restart on the next
+instruction. Hope we don't want to do anything fancy with breakpoint! Note
+that I had breakpointing contexts restart on other pcores and continue while I
+was in the breakpoint handler (noticed while I was debugging some bugs with
+lots of preempts). Yikes. And don't forget we eventually want to do some
+complicated things with the page fault handler, and may want to turn on
+interrupts / kthread during a page fault (imaging hitting disk). Yikes.
+So I looked into going back to ROUTINE kernel messages. With ROUTINE
+messages, I didn't have to worry about having the carpet pulled out from under
+syscalls and exceptions (traps, faults, etc). The 'carpet' is stuff like
+cur_ctx, owning_proc, owning_vcoreid, etc. We still cannot trust the vcoremap,
+unless we *know* there were no preempts or other KMSGs waiting for us.
+(Incidentally, in the recent fix a93aa7559, we merely use the vcoremap as a
+sanity check).
+However, we can't just switch back to ROUTINEs. Remember: with ROUTINEs,
+we will deadlock in '__map_vcore()', when it waits for the completion of
+preempt. Ideally, we would have had startcore spin on the signal. Since we
+already gave up on using x86-style broadcast IPIs for startcore (in
+5343a74e0), we might as well pass along a history counter, so it knows to wait
+on preempt.
+9.4: The Solution
+To fix up all of this, we now detect preemptions in syscalls/traps and order
+our kernel messages with two simple per-vcore counters. Whenever we send a
+preempt, we up one counter. Whenever that preempt finishes, it ups another
+counter. When we send out startcores, we send a copy of the first counter.
+This is a way of telling startcore where it belongs in the list of messages.
+More specifically, it tells it which preempt happens-before it.
+Basically, I wanted a partial ordering on my messages, so that messages sent
+to a particular vcore are handled in the order they were sent, even if those
+messages run on different physical cores.
+It is not sufficient to use a seq counter (one integer, odd values for
+'preempt in progress' and even values for 'preempt done'). It is possible to
+have multiple preempts in flight for the same vcore, albeit with startcores in
+between. Still, there's no way to encode that scenario in just one counter.
+Here's a normal example of traffic to some vcore. I note both the sending and
+the execution of the kmsgs:
+ nr_pre_sent nr_pre_done pcore message sent/status
+ -------------------------------------------------------------
+ 0 0 X startcore (nr_pre_sent == 0)
+ 0 0 X startcore (executes)
+ 1 0 X preempt (kmsg sent)
+ 1 1 Y preempt (executes)
+ 1 1 Y startcore (nr_pre_sent == 1)
+ 1 1 Y startcore (executes)
+Note the messages are always sent by the lockholder in the order of the
+example above.
+Here's when the startcore gets ahead of the prior preempt:
+ nr_pre_sent nr_pre_done pcore message sent/status
+ -------------------------------------------------------------
+ 0 0 X startcore (nr_pre_sent == 0)
+ 0 0 X startcore (executes)
+ 1 0 X preempt (kmsg sent)
+ 1 0 Y startcore (nr_pre_sent == 1)
+ 1 1 X preempt (executes)
+ 1 1 Y startcore (executes)
+Note that this can only happen across cores, since KMSGs to a particular core
+are handled in order (for a given class of message). The startcore blocks on
+the prior preempt.
+Finally, here's an example of what a seq ctr can't handle:
+ nr_pre_sent nr_pre_done pcore message sent/status
+ -------------------------------------------------------------
+ 0 0 X startcore (nr_pre_sent == 0)
+ 1 0 X preempt (kmsg sent)
+ 1 0 Y startcore (nr_pre_sent == 1)
+ 2 0 Y preempt (kmsg sent)
+ 2 0 Z startcore (nr_pre_sent == 2)
+ 2 1 X preempt (executes (upped to 1))
+ 2 1 Y startcore (executes (needed 1))
+ 2 2 Y preempt (executes (upped to 2))
+ 2 Z Z startcore (executes (needed 2))
+As a nice bonus, it is easy for syscalls that care about the vcoreid (yield,
+change_to, get_vcoreid) to check if they have a preempt_served. Just grab the
+lock (to prevent further messages being sent), then check the counters. If
+they are equal, there is no preempt on its way. This actually was the
+original way we checked for preempts in proc_yield back in the day. It was
+just called preempt_served. Now, it is split into two counters, instead of
+just being a bool.
+Regardless of whether or not we were preempted, we still can look at
+pcpui->owning_proc and owning_vcoreid to figure out what the vcoreid of the
+trap/syscall is, and we know that the cur_ctx is still the correct cur_ctx (no
+carpet pulled out), since while there could be a preempt ROUTINE message
+waiting for us, we simply haven't run it yet. So calls like yield should
+still fail (since your core has been unmapped and you need to bail out and run
+the preempt handler), but calls like sys_change_stack_pointer can proceed.
+More importantly than that old joke syscall, the page fault handler can try to
+do some cool things without worrying about really crazy stuff.
+9.5: Why We (probably) Don't Deadlock
+It's worth thinking about why this setup of preempts and startcores can't
+deadlock. Anytime we spin in the kernel, we ought to do this. Perhaps there
+is some issue with other KMSGs for other processes, or other vcores, or
+something like that that can cause a deadlock.
+Hypothetical case: pcore 1 has a startcore for vc1 which is stuck behind vc2's
+startcore on PC2, with time going upwards. In these examples, startcores are
+waiting on particular preempts, subject to the nr_preempts_sent parameter sent
+along with the startcores.
+| _________ _________
+| | | | |
+| | pr vc 2 | | pr vc 1 |
+| |_________| |_________|
+| _________ _________
+| | | | |
+| | sc vc 1 | | sc vc 2 |
+| |_________| |_________|
+ ______ ______
+ | | | |
+ |______| |______|
+Here's the same picture, but with certain happens-before arrows. We'll use X --> Y to
+mean X happened before Y, was sent before Y. e.g., a startcore is sent after
+a preempt.
+| _________ _________
+| | | | |
+| .-> | pr vc 2 | --. .----- | pr vc 1 | <-.
+| | |_________| \ / & |_________| |
+| * | \/ | *
+| | _________ /\ _________ |
+| | | | / \ & | | |
+| '-- | sc vc 1 | <-' '----> | sc vc 2 | --'
+| |_________| |_________|
+ ______ ______
+ | | | |
+ |______| |______|
+The arrows marked with * are ordered like that due to the property of KMSGs,
+in that we have in order delivery. Messages are executed in the order in
+which they were sent (serialized with a spinlock btw), so on any pcore,
+messages that are further ahead in the queue were sent before (and thus will
+be run before) other messages.
+The arrows marked with a & are ordered like that due to how the proc
+management code works. The kernel won't send out a startcore for a particular
+vcore before it sent out a preempt. (Note that techincally, preempts follow
+startcores. The startcores in this example are when we start up a vcore after
+it had been preempted in the past.).
+Anyway, note that we have a cycle, where all events happened before each
+other, which isn't possible. The trick to connecting "unrelated" events like
+this (unrelated meaning 'not about the same vcore') in a happens-before manner
+is the in-order properties of the KMSGs.
+Based on this example, we can derive general rules. Note that 'sc vc 2' could
+be any kmsg that waits on another message placed behind 'sc vc 1'. This would
+require us having sent a KMSG that waits on a KMSGs that we send later. Bad
+idea! (you could have sent that KMSGs to yourself, aside from just being
+dangerous). If you want to spin, make sure you send the work that should
+happen-before actually-before the waiter.
+In fact, we don't even need 'sc vc 2' to be a KMSG. It could be miscellaneous
+kernel code, like a proc mgmt syscall. Imagine if we did something like the
+old '__map_vcore' call from within the ksched. That would be code that holds
+the lock, and then waits on the execution of a message handler. That would
+deadlock (which is why we don't do it anymore).
+Finally, in case this isn't clear, all of the startcores and preempts for
+a given vcore exist in a happens-before relation, both in sending and in
+execution. The sending aspect is handled by proc mgmt code. For execution,
+preempts always follow startcores due to the KMSG ordering property. For
+execution of startcores, startcores always spin until the preempt they follow
+is complete, ensuring the execution of the main part of their handler happens
+after the prior preempt.
+Here's some good ideas for the ordering of locks/irqs/messages:
+- You can't hold a spinlock of any sort and then wait on a routine kernel
+ message. The core where that runs may be waiting on you, or some scenario
+ like above.
+ - Similarly, think about how this works with kthreads. A kthread restart
+ is a routine KMSG. You shouldn't be waiting on code that could end up
+ kthreading, mostly because those calls block!
+- You can hold a spinlock and wait on an IMMED kmsg, if the waiters of the
+ spinlock have irqs enabled while spinning (this is what we used to do with
+ the proc lock and IMMED kmsgs, and 54c6008 is an example of doing it wrong)
+ - As a corollary, locks like this cannot be irqsave, since the other
+ attempted locker will have irq disabled
+- For broadcast trees, you'd have to send IMMEDs for the intermediates, and
+ then it'd be okay to wait on those intermediate, immediate messages (if we
+ wanted confirmation of the posting of RKM)
+ - The main thing any broadcast mechanism needs to do is make sure all
+ messages get delivered in order to particular pcores (the central
+ premise of KMSGs) (and not deadlock due to waiting on a KMSG improperly)
+- Alternatively, we could use routines for the intermediates if we didn't want
+ to wait for RKMs to hit their destination, we'd need to always use the same
+ proxy for the same destination pcore, e.g., core 16 always covers 16-31.
+ - Otherwise, we couldn't guarantee the ordering of SC before PR before
+ another SC (which the proc_lock and proc mgmt code does); we need the
+ ordering of intermediate msgs on the message queues of a particular
+ core.
+ - All kmsgs would need to use this broadcasting style (couldn't mix
+ regular direct messages with broadcast), so odds are this style would be
+ of limited use.
+ - since we're not waiting on execution of a message, we could use RKMs
+ (while holding a spinlock)
+- There might be some bad effects with kthreads delaying the reception of RKMS
+ for a while, but probably not catastrophically.
+9.6: Things That We Don't Handle Nicely
+If for some reason a syscall or fault handler blocks *unexpectedly*, we could
+have issues. Imagine if change_to happens to block in some early syscall code
+(like instrumentation, or who knows what, that blocks in memory allocation).
+When the syscall kthread restarts, its old cur_ctx is gone. It may or may not
+be running on a core owned by the original process. If it was, we probably
+would accidentally yield that vcore (clearly a bug).
+For now, any of these calls that care about cur_ctx/pcpui need to not block
+without some sort of protection. None of them do, but in the future we might
+do something that causes them to block. We could deal with it by having a
+pcpu or per-kthread/syscall flag that says if it ever blocked, and possibly
+abort. We get into similar nasty areas as with preempts, but this time, we
+can't solve it by making preempt a routine KMSG - we block as part of that
+syscall/handler code. Odds are, we'll just have to outlaw this, now and
+forever. Just note that if a syscall/handler blocks, the TF it came in on is
+probably not cur_ctx any longer, and that old cur_ctx has probably restarted.

subset: commoncrawl


text:
The best way to book for your clients is directly with us. Here you can do so comfortably and receive instant confirmation. As well as accessing the best conditions, your agency will be registered.
The best option for you, for your clients and for us. Use your identification code or request one from us.
Our hotel is delighted to welcome clients who are travelling on business. If you stay under your company's name or if you wish to make a booking for one of your company's employees, do it directly with us from here.
You can book in just two minutes, receive instant confirmation and your company will be registered. Use the code we have provided you with or request one from us if you still do not have one.
Please be sure to complete de items marked with an asterisk (*).


text:
Optacryl 60
1 Lens$34.95
$105.00You Save $70.05
Buy More Save More!$29.99 Buy 2+ per eye
$105.00You Save $75.01
Prescription Information:
- OD right eye
- OS left eye
- Brand name eg. Acuvue
- BC / Base Curve a number between 8.0 and 10.0
- DIA / Diameter a number between 13.0 and 15.0
- Power / Sphere / Rx a number between -20 and +20
In Addition for astigmatic patients:
- Cylinder a number between -4.00 and +4.00
- Axis a number between 0 and 180
- Cylinder and Axis are usually separated by a x
For Multifocal, Bifocal lenses or Presbyopia:
"Addition" or "add" is usually preceded by "+" or is listed as "low", "mid" or "high" depending on the lens manufacturer.
MONEY BACK GUARANTEE Complete Details
HASSLE FREE RETURNS Complete Details
Optacryl 60 Reviews
Wanna save money? Wear the Optacryl 60.
I tried out the Optacryl 60 about 4 years ago and I have been wearing it ever since. I switched because I was sick of always buying disposable contact lenses and spending so much money. Now I just buy one pair a year and that's it. Wearing this contact lens is a pretty easy way to save money. The lens is super comfortable and it gives me great vision, what else do I need?!?!
Optacryl 60 are awesome
These contact lenses are so comfortable. All the other RGP's I had over the year never seemed like the fit my eye a 100%., they often irritated my eye and seemed to fall out quite a bit. I don't have this problem with Optacryl 60 lenses. These lenses are a perfect fit and never bother my eyes. I can use these lenses for a very long time which is great.
Product Information
Optacryl 60 contact lenses are rigid gas permeable lenses manufactured by Paragon Vision Sciences. The lenses feature a lathe cut and spherical front and back surfaces to provide a superior fit and full correction of refractive errors. This design ensures stability and a clear view in all light settings. Optacryl 60 contact lenses feature a peripheral curve system on the outer surface that fosters effective tear exchange between the lens and the cornea, which contributes to improved comfort and moisturization.
A high Dk rating indicates that the lenses supply large amounts of oxygen to the eyes to improve ocular health and create a whiter and brighter appearance of the sclera. Optacryl 60 contact lenses come with an optional tint in blue, green, and gray, so you can enjoy user-friendly handling and easier application. The lenses last for up to one year of daily wear with regular cleaning and storing, which offers optimal convenience to any schedule.
A water-free construction eliminates the likelihood of bacterial growth and deposit build-up, which ensures better comfort and health. Despite the fact that Optacryl 60 contact lenses don't contain water, they feature a highly wettable surface that locks in moisture for a refreshing feeling from day to night.
Product Availability
This item normally ships within 1 - 2 business days.
Price Comparison
|Our Lowest Price
|Retail Price
|Your Savings
ManufacturerParagon Vision Sciences
Material Content
100% Polymer (sil/acryl)
Water Content


text:
Europe's Week Ahead: BOE Back in Focus
Bank of England minutes are out next week and should give some more background on Gov. Mark Carney's new hawkish stance. Final euro-zone inflation data for May, a Eurogroup meeting and H&M results will also keep investors busy.
This transcript has been automatically generated and may not be 100% accurate.
I ... it's windy that I don't and is up to period eerie calm ... the CTS as tensions in Iraq continues to hocus Bank of England ... the necessary here with me to discuss what's going to be feeding it that makes next week ... I wouldn't be hearing of more inflation in the euro zone ... otherwise on that I think he's going to come down ... a stunning fall out of bed at Mittleman said in an inflation data and oh so if the make or break it into four for the ECB will have the final reading from a next week ... and what is the only to put out their major stimulus package people so that watching in just to see if inflation ... is co-founder point five percent for men which was the lowest in more than four years so ... if it falls below that I think I still see people are getting a bit concerned toss ups about deflation risk but ... to say they do at the low friction the ECB in rebuilding it did almost everything ... I'm now a technical point ... the ECB is also thinks of ending its sterilization is is that the Essen P keeps us but ... to me well is the sort of like a mini cinema as an injection way it effects the means that more than a hundred billion euros will be pumped into the and your senses ... so that should mean that the euro Biffle maybe a bit I can't wait to see if and when the baby coming into your seventy fifth like a mini form of QE ... informally ... I miss the action increases well victim more this week on all star team as if to teach ... what can happen ... from the Eurogroup of finance ministers meet next week and added the official agenda is not good but expectations on him that I can be the boundaries of the design and one ... they they want that and and and a five to twelve point six billion euro funding to at least three so this'll have ... to pick out what to do with the so the goodness of missteps during matches interesting stuff but for ... now Bank of England Governor Mark Carney said ... my son has stated that UK interest rates could rise sooner than the mock it's expecting which she gets a visibility on the next week will we see that back in the minutes of some of those discussions on the line that says the ... tussle ... over the last minutes but you banking because the biggest advantage Markets because it ... looks like it's a bit more about what he think about when the pressured to raise rates ... and the policeman the Fed Cup debut significant guidance about when ... when they should be hard ... and it's coming from a state when people with the matter was bracing for twenty ... one ... say ... to be in focus I had a cough it's the release of the ... Commons members since the death of houses like that bit more time to make these ... will be looking for clues to see when they find they will start to raise interest rates as the SakeOne didn't warn ... about ... the housing market and strengthen the burial the economy ... I'm so will be into next week ... with that with the same ... way that may well be some ... discussion around ... splicing and most US mortgage frontier for instance but the Phils on that would be released until the funding between him and pull up a kiss a will to achieve this well okay I this summing up in the US is well and the FOMC meeting is next week but we stayed autopilot for tapering again so ... was a kid and a nickel cobalt exams report came as the scoff results this is every till bellwether it's it's you know what that what we can see ... where second-quarter house that's been very good ration and that has a strong quarter self CPN may ... I miss this is raising hopes that maybe this course with effort and the school to ... but thinks claimed the some concerns that ... that that the sales to be strong because they can be made aggressively market down ... and it's it's price is ... aggressively unit pricing if they still ... under ... the high because as around Christlike a sight to them and if that is the case ... this way it may well


text:
Portrait of a Young Man Trying to Draw
Portrait of a Young Man Trying to Draw consists of ten scratchboard images (on linen paper) in a beautiful, hand bound and die cut package by artist William Schaff, best known for his album art for such bands as Godspeed You! Black Emperor and Okkervil River. Signed and numbered in an edition of 500.


text:
Jason Lowenstein is a punk rock superhero, that's the first thing to get straight otherwise the deal's off. A disciple of the true and noble word of Rock. Lowenstein has torn up and spat out the road and any other obstacle on his righteous path to The Real Thing. The sound of the eternal riff, the teenage howl, the snare pound rising from the basement, the AM dial tuned in by the hand of pot. The head is nodded, the arms outstretched and we are ready to blow momma, cause it's a heavy load. Cranked out and taped by the jackhammer Lowenstein hands alone. Fourteen songs that blister, chug, sweat and spit. There is painful honesty: 'I'm A Shit'. There is playful technique: 'Crazy Santana' and there is the communication breakdown and eternal stew of human interaction: 'Codes', 'Casserole'. There is bonged-out paranoid introspection: 'More Drugs', 'Mistake'. But most of all there is Rock. All-American balls to the wall Rock. Amps-cranked-tunes -nailed Rock.
This artist is a member of Sebadoh.


text:
Note: If your currently installed zPCR version is older than C9.0, it MUST be uninstalled prior to installing zPCR C9.4a (package includes Java). This is necessary to facilitate conversion to the new IBM Java v8 64-bit runtime environment that is required for zPCR.
To review the zPCR C9.4a NEWS file, click on What's New below.
Performance data contained in this document was determined in a controlled environment; therefore the results which may be obtained in other operating environments may vary significantly. No commitment as to your ability to obtain comparable results is any way intended or made by this release of information.
zPCR estimates have a degree of error of +/- 5%. Customers using zPCR information are solely responsible for building capacity plans using zPCR results which accommodate the degree of error inherent in the tool.
End of Life Statement for zPCR
Frequently Asked Questions
How are the IBM z15 models identified?
How are the IBM z14 models identified?
How are the IBM z13 models identified?
How are the IBM zEnterprise EC12 models identified?
How are the IBM zEnterprise 196 models identified?
How are the IBM System z10 EC models identified?
How are the IBM System z9 EC models identified?
The IBM System z9 EC has 5 models. The models support different number of processor units (PU) which are configurable as General Purpose CPs, zAAPs, zIIPs, IFLs, ICF's, or optional SAPs.
System z9 EC Models S08 - Supports 1 to 8 Configurable PUs
S18 - Supports 1 to 18 Configurable PUs
S28 - Supports 1 to 28 Configurable PUs
S38 - Supports 1 to 38 Configurable PUs
S54 - Supports 1 to 54 Configurable PUs
In addition, for General Purpose CPs, there are 4 engine speeds, listed below in increasing speed sequence. All zAAPs, zIIPs, IFLs, and ICFs are full speed CPs.
400 Limit of 8 General Purpose CPs
500 Limit of 8 General Purpose CPs
600 Limit of 8 General Purpose CPs
700 No limit for General Purpose CPs
How are the IBM zSeries 990 models identified?
How often will I need to register my use of zPCR?
What versions of Windows will support zPCR?
When must I reinstall the IBM Java runtime environment?
Learn more


text:
Lancaster Republican party sitting out of major races
GOP says potential candidates are unready, or uninterested
In Lancaster, the Republican party is sitting out of some major races. The Lancaster City GOP says its potential candidates for mayor either aren't ready or aren't interested in running this year.
Former Mayor Charlie Smithgall says he was asked by the party to run against Mayor Rick Gray this year, but eventually declined the offer.
Smithgall had some success against Gray in 2009, losing by slightly more than 300 votes.
Republican committee leaders say that the party is now taking the time off to reintroduce itself to the community by sponsoring events, speaking one on one with residents, and looking for fresh new candidates, all in an effort to help its chances next time around.
The party says it's outnumbered almost three to one by Democrats and even if it can get out all of its voters, any race is still an uphill battle.
Party leaders also say the national political debate is hurting its efforts downtown.
"With the national level of unhappiness with the Republican Party, it's trickling down to the local level. So our goal is to put ourselves back out into the community so people can realize who we truly are and what we stand for," says Republican Committee Chair Lisa Colon.
In addition to the mayoral race, Lancaster Republicans aren't running any candidates against the four city council Democrats up for re-election.


text:
Notorious B.I.G's Autopsy Report Leaked in Detail
In March 1997, Notorious B.I.G. was slain in Los Angeles when four bullets pierced through his body while he was sitting in the passenger seat of a Chevy Suburban. Now, an unsealed autopsy explains the exact nature of how the late rapper died of his injuries.
TMZ uncovered the never-before-seen coroner's report and it reveals some very graphic details.
According to the report, Biggie (real name Christopher Wallace) was shot four times but three of the bullets were not fatal. One gunshot entered the left forearm and traveled down to his wrist. The second gunshot hit B.I.G. in the back but missed all vital organs and exited through his left shoulder. The third gunshot passed through his outer left thigh, grazing his scrotum before exiting the leg.
It was the fourth gunshot that ultimately killed the then 24-year-old rapper. That fatal bullet entered his right hip and passed through several vital organs including his heart, liver and upper lobe of his left lung.
B.I.G. was rushed to Cedars-Sinai Hospital immediately after the shooting, where doctors performed an emergency thoracotomy but it was too late. He was officially pronounced dead at 1:15AM CT.
The autopsy also listed Biggie as "morbidly obese" at 6'1", 395 pounds. A toxicology test also revealed that he had no traces of drugs or alcohol in his system at the time of his death. The coroner, clearly unaware of the legend, wrote in his notes: "Decedent may be rap singer."
It has been 15 years since Biggie's slaying and the homicide case remains unsolved. In March 2012, Los Angeles police detective Greg Kading, who was assigned to investigate B.I.G.'s murder case between 2006 and 2009, told Complex that the case may never get solved.
May Notorious B.I.G. rest eternally in peace.
Watch the Notorious B.I.G. 'Big Poppa' Video


text:
It's sweltering in my house. I was dripping sweat earlier. I went outside earlier, to try and benefit from the meager breeze coming from the bay, and my outdoor furniture was wet from a storm that had passed by earlier but I didn't even care. That's how hot it is.
I'm not telling you this for sympathy. I think I'm building character.
My life is quiet and small and plain. Again, I'm not telling you this for sympathy or vague reassurance that my life is not the way I perceive it (that just makes someone feel crazy, doesn't it?). I'm telling you this to illuminate my character, because this realization makes me restless. I always feel like I'm wasting my time and my youth, that I should be doing more, more, more. So I'm taking baby steps to do just that.
On Wednesday, I went to Princeton with one of my best friends. We strolled the campus like we belonged there, despite me being clad in clothes purchased from Old Navy and not J. Crew or Ann Taylor or anywhere else equally as impressive and expensive. Not only that, but an intrusive coffee stain that was too large to be ignored assaulted the lower-half of my shirt in a way that simply screamed I didn't belong, that I was totally and completely faking it. But I didn't let my general sloppiness ruin the trip – I'm not that dramatic.
I dragged my patient and impossibly too kind friend to the university to peruse the F. Scott Fitzgerald archives. I anticipated manuscripts and pictures kept under class in a far and quiet corner of the library. I assumed the public had free and easy access to the most personal belongings of a literary genius, but I was so wrong. We had to register, received photo identification cards to enter a restricted part of the library, wash our hands, lock away our belongings, and specifically select which aspects of Fitzgerald's life we wanted to access. We did this without complaint (which is saying something considering the heat of the day was blistering and my dear, dear friend never intended to spend 150 minutes looking at the personal affects of some dead author), and were shown into a reading room. There, I made plans to visit Great Neck, Long Island for a long weekend (the setting that inspired The Great Gatsby) and to travel to Hackensack, New Jersey (specifically to see the Newman School, which Fitzgerald attended). My friend and I both flipped through a sort of combined scrapbook of Scott and Zelda, compiled by Matthew J. Bruccoli (the only Fitzgerald biographer that matters) and Scottie, Scott and Zelda's daughter.
Scott's drama teacher wrote, "Good God, save the soul of the man with the spark!" in reference to Fitzgerald. What a tragedy; what a shame.
We were presented with a facsimile of the manuscript of The Great Gatsby, complete with edits and revisions in Fitzgerald's own handwriting, not to mention the entire manuscript was handwritten. I nearly cried.
We read letters from Zelda to Scott, which chronicled the beginnings of their relationship, as well as the more tumultuous aspects of the courtship and marriage. I compiled a list of Zelda's best quotes.
- … it's so easy, and believing is much more intelligent
- And still I'm so mighty happy — It's just sort of a "thankful" feeling — that I'm alive and that people are glad I am
- There's nothing to say — you know everything about me, and that's mostly what I think about. I seem always curiously interested in myself, and it's so much fun to stand off and look at me …
- … something always makes things the way they ought to be …
- I love you sad tenderness — when I've hurt you — That's one of the reasons I could never be sorry for our quarrels — and they bothered you so — Those dear, dear little fusses, when I always tried so hard to make you kiss and forget
- … It seems as if there's no new wisdom — and surely people haven't stopped thinking — I guess morality has relinquished its claim on the intellect — and the thinkers think dollars and wars and politics — I don't know whether it's evolution or degeneration
- To be afraid, a person has either to be a coward or very great and big
- … free to sit in the sun and choose the things I like about people and not have to take the whole person
- It is odd that the heart is one of the organs that does repair itself
I loved the eccentric, charming and dangerous and alarming details I learned about their love, like how Zelda consulted a Ouija board, and how she blamed Scott for her mental illness but firmly believed he could cure her.
We read Scott's letters with a painstaking clarity, as we knew of the end he didn't see coming. It was heartbreaking, really.
I decided the goal is to write the last chapter of my next book in the Nassau Inn, to truly channel the passion and vibrancy and tragedy of F. Scott Fitzgerald.
I found some places I'd like to visit in France, places Fitzgerald went to and found some kind of inspiration, whether for writing or living large.
We wandered around campus for a while longer, sneaking into classrooms, disrupting tour groups, and feeling – even if for just a little while – that grand things were still possible for us.
We ventured into the cathedral on campus and a Starbucks and a book store to beat the heat.
We traveled to Asbury Park for some live music and great company. It was a great day, the kind summers are made of. I intend to have more like them.
I was inspired to write the following short story. Enjoy!
by Mandi Bean
Carlos knew that the equator separated the globe into northern and southern hemispheres, and Carlos also knew that the farther south a person traveled, the hotter the weather became. However, Carlos could testify to the fact, and possibly even prove, that the farther west a person traveled, the same phenomenon occurred. He had lived on the eastern shore of New Jersey his entire life and could say without hesitation, could say with near absolute certainty, that the middle of the state was a burning, boiling wasteland in July – the most uncomfortable Summer month to begin with – and that it served no real purpose. Carlos had traveled west at the request of his fashionable, trendy girlfriend and now regretted it something fierce.
They were traipsing about the campus of Princeton University so that his girlfriend could admire the rich history and breathtaking architecture and blah, blah, blah. It was ninety-three degrees and Carlos was miserable. He felt damp and disgusting in places he didn't even know could sweat. Still, he took it all in stride, trying to keep his girlfriend happy and blissfully unaware of his discomfort. He said nothing as they walked innumerable staircases to gawk at old buildings and open fields that meant something to someone somewhere, sure, but that person was not Carlos. His mood dangled precariously between "thoughtfully quiet" and "crankily homicidal," and he offered his girlfriend only interested smiles as she prattled on and on about tradition and excellence and whatever.
Carlos only perked up as they neared the center of the sprawling campus. There was a pool, six inches deep at the most, with a fountain at its center, an impressive, enigmatic modern sort of structure spouting water. Carlos took his girlfriend's hand and rushed towards it, the way someone might rush towards a miraculous pool while stranded in a desert. But this pool and fountain was no mirage; children splashed here and there, supervised by patient adults who smiled and nodded with a calculated, weary sort of encouragement. Carlos reached the pool's edge, where wide, flat stone steps led down to the water. He was smiling wide, with a youthful exuberance, and he turned to his girlfriend. "I'm going in," he stated and sat down to remove his shoes and socks.
His girlfriend offered a sweet smile, totally enchanted by Carlos' juvenile need to cool and comfortable, by his childish ambitions. He was a beautiful young man with dark features that made him appear to be super intellectual, but in reality, he was nothing of the sort. But his girlfriend, equally as beautiful, was not disturbed by Carlos' lack of desire for education and all things brainy. It kept her in check, kept a balance in the relationship. "Go right ahead," she smiled. "I'll wait here."
Carlos paused and looked up at her. "You're not coming in? This heat is brutal."
She shook her head and seated herself beside Carlos. "It's hot, but I'm okay. You go in, though. I can't tell you're dying to." She leaned against him for a moment to kiss his cheek. That was all the permission Carlos needed, and he took off, splashing with reckless abandon to reach the fountain at the center. That spewing, falling water was the most efficient way to get cool. He passed the laughing, shrieking children and paused at the base of the fountain. The water fell on him in the most refreshing way and he was content to simply exist, it simply be in a world where water was free to fall where it may. What a time to be alive, what with fountains and pools to keep the intense summer heat at bay. He closed his eyes and attempted to wash away the sweat and sourness of the July sun.
After a few moments, he opened his eyes and leveled his gaze. He was surprised to find another adult, another wanderer about campus, engaging in the same activity. She was gorgeous, and Carlos also noted the way the woman had been equally as daring, had strode in the same way Carlos had, not caring for the onlookers or any kind of judgments. There was only the oppressive heat, and the refreshing relief of the water, roaring down from the fountain and tinkling as it reached the pool surface. They both appreciated the opportunity, had seized it, and now stood breathless, together in their choices and ideology, but separate in their strangeness to the other.
Carlos breathed a simple "hey."
The woman nodded, and kicked water up at Carlos. That was her greeting; that was it. Aside from the playful smile, she had offered nothing, not even her name. But Carlos was game. He returned the splash. In a matter of moments, Carlos and the woman were doing their best to drown each other. Their raucous laughter and innocent challenges drowned out that of the children and even the most dutiful of supervising parent stole a glance at the two grown adults making complete asses of themselves in the fountain on the campus of Princeton University.
But, as do all things in life, the splashing lost its appeal and became old and tired. Carlos looked back to his girlfriend and found her reading (there was always a book in her over sized bag). He waved goodbye to the gorgeous, wild and free woman he had spent the last ten minutes with. Without really thinking about it, Carlos returned to the studious, safe and responsible woman waiting for him out of the water. He supposed that was the way it was supposed to be, that for every soul willing to get lost at sea, there had to be another anxiously waiting on shore.
As he came nearer, dripping wet and breathless and smiling, Carlos' girlfriend looked up and barked a laugh. "Am I glad you drove," she teased, "because you would never ever get into my car like that."
Carlos bent to swiftly kiss her before she could protest or squirm away.


text:
We often get so caught up in who's on the injury report that we overlook who isn't.
Saints tight end Jimmy Graham has exited the injury report, four weeks after spraining his ankle, two weeks after missing a game against the Buccaneers, and one week after being a game-time decision for a Sunday night game against the Broncos.
The fact that he's not on the report, not even as probable, means that he's no longer injured at all — if the Saints are interpreting the injury-reporting rules the way the Ravens do now, not before they were fined $20,000 for failing to report the shoulder injury to Ed Reed.
Only four players are on the Saints' injury report in advance of Monday night's game against the Eagles. Running back Darren Sproles (hand) and receiver Courtney Roby (foot) are out, and linebacker David Hawthorne (hamstring) and receiver Joe Morgan (chest) are probable.


text:
1. Re: JBoss Third Party Buildstarksm64 Jun 22, 2005 10:40 PM (in response to ruel.loehr)
Ok, but I first want to see 4.0 building from a repository generated thirdparty structure which only entails getting the repository populated for 1).
For 2), the existing jboss-4.0/build/build-thirdparty.xml needs to be populated with the componentrefs for the thirdparty repository libraries needed to build the server.
3-5 are the same.
I'm thinking that it will take less to get this working for 4.0 than introducing component-info.xml for every module. If you don't think this is the case, fine, but this needs to be working for the 4.0.3 release.
2. Re: JBoss Third Party Buildruel.loehr Jun 24, 2005 3:53 PM (in response to ruel.loehr)
I worked with this yesterday and created a build-thirdparty.xml based off of what was in the thirdparty directory in the 4.0 branch. I found a couple of things that will need clarification.
1) hibernate thirdparty vs. hibernate module
Currently when we try to pull down the thirdparty modules the build sees a directory "hibernate" (our integration module). Because this module exists it will not pull down the thirdparty component "hibernate". How should we resolve this? The way the build is currently structured a thirdparty component cannot have the same name as a source module. Should the hibernate thirdparty be moved to jboss/hibernate?
2) what we use vs. what is there
If I go through every module under 4.0 (e.g. iiop, varia) looking at the build.xml file and look at what library classpaths are defined, and then creating a list of all library dependencies required, the list does not match the number of items in thirdparty. I assume some items in thirdparty (the early version of tomcat for example) are no longer used. Should I base the generated libraries.ent off of the cvs thirdparty dir as a whole, or just off of what is used.
3) naming conventions
Currently in the repository we have some dual directories, one called juddi, one called juddi-juddi. Which should I base off of?
4) new thirdparty items
In some cases, such as apache commons, the jars have been moved to their own repository locations. Won't this necessitate a change to the build.xml files ?
Ruel Loehr
3. Re: JBoss Third Party Buildryan.campbell Jun 24, 2005 4:08 PM (in response to ruel.loehr)
1. This is a by product of using the directory name as the component id. We might be able to fix jbossbuild to have two components by the same name, one in thirdparty and one source component, but I'm afraid this leads to ambiguity.
We shouldn't rename the thirdparty hibernate. If anything, the hibernate integration module needs to be renamed to hibernate-intg or something.
2. just what is being used.
3. We aren't using the double named convention anymore, so just use juddi. Make sure it has the correct version from the 4.0 versions.xml
4. Yes it will, but let's commit what we have before making changes to build.xmls.
4. Re: JBoss Third Party Buildstarksm64 Jun 24, 2005 11:26 PM (in response to ruel.loehr)
1) This is because there is a notion of a component and it can be either a source or binary module? The hibernate integration module can be changed in the current jboss-4.0.x definition:
jboss-4.0.x -d jboss-4.0 \ &_jboss_aop \ ... -d har hibernate \ ...
The build.xml modules reference to hibernate would have to be changed locally to do the build.
2) There certainly is tons of garbarge in there. The thirdparty build should be created by only referencing the direct dependencies of the toplevel components. Build the thirdparty strucuture and try the build and add thirdparty componentrefs as needed until it builds.
3) As Ryan said, drop the double name usage as its a cvs hack issue that we should not propagate.
4) The only place the new thirdparty lib names should be showing up at is in the libraries.ent definitions. Nearly all build files in the modules should simply be referencing the *.classpath from librariens.ent. The only problem will be that there will not be an aggregate classpath like apache.commons.classpath. You could deal with this by adding a notion of being able to merge multiple component paths to the libraries.ent generation:
<path id="apache.commons.classpath"> <componentref id="apache-lang" /> <componentref id="apache-logging" /> <componentref id="apache-modeler" /> ... </path>
5. Re: JBoss Third Party Buildruel.loehr Jun 25, 2005 5:47 PM (in response to ruel.loehr)
Excellent! That leaves me with only two references from the collection of build.xml files that I am not sure how to handle.
1) ant
The current libraries.ent has an entry for ant.
<!-- Ant --> <property name="apache.ant.root" value="${project.tools}"/> <property name="apache.ant.lib" value="${apache.ant.root}/lib"/> <path id="apache.ant.classpath"> <pathelement path="${apache.ant.lib}/ant.jar"/> </path>
The version of ant is found in the tools directory, not in the thirdparty. For the generated libraries.ent to have an entry for it, it would need to exist in the repository. How should we handle this?
2) EJB-Pesistence
The current libraries.ent handles ejb-persistence like this:
<!-- hibernate3 --> <property name="hibernate.root" value="${project.thirdparty}/hibernate"/> <property name="hibernate.lib" value="${hibernate.root}/lib"/> <path id="hibernate3.classpath"> <pathelement path="${hibernate.lib}/hibernate3.jar"/> <pathelement path="${hibernate.lib}/hibernate-annotations.jar"/> <pathelement path="${hibernate.lib}/asm.jar"/> <pathelement path="${hibernate.lib}/asm-attrs.jar"/> <pathelement path="${hibernate.lib}/antlr*.jar"/> </path> <!-- ejb3-persistence --> <path id="ejb3-persistence.classpath"> <pathelement path="${hibernate.lib}/hibernate-annotations.jar"/> <pathelement path="${hibernate.lib}/hibernate-entitymanager.jar"/> <pathelement path="${hibernate.lib}/ejb3-persistence.jar"/> </path>
An ejb3-persistence classpath is defined, but it is part of hibernate (in the directory structure). The same problem exists as with ant. For an entry to be generated, it needs to have its own repository location, but does it make sense to break this out as a seperate entity?
Ruel Loehr
JBoss QA
6. Re: JBoss Third Party Buildstarksm64 Jun 25, 2005 6:31 PM (in response to ruel.loehr)
1) Ant should be in the repository as well, but currently we do not include it into jboss. Tomcat used to until the switch to the jdt compiler. As of now there should be no need for this in libraries.ent.
2) So really, hibernate, hibernate annotations, and hibernate entitymanager (which is what I assme has the ejb3-persistence.jar artifact, ask Bill or Emmanuel) should be seperate entries in the repository as they are three seperate releases currently:
7. Re: JBoss Third Party Buildruel.loehr Jul 1, 2005 4:01 PM (in response to ruel.loehr)
I committed an initial pass at the thirdparty-build.xml file. At this point it should be a very close representation of what is required to build the 4.0 branch.
I am sure other adjustments will be required after generating the libraries.ent and attempting building (my next task) (e.g changing module names of hibernate & xdoclet).
user instructions:
mkdir test
cd test
cvs co -r Branch_4_0 jboss-4.0.x
cd jboss-4.0
cd build
ant -f build-thirdparty.xml
cd ../thirdparty
Ruel Loehr
JBoss QA
8. Re: JBoss Third Party Buildstarksm64 Jul 5, 2005 10:56 AM (in response to ruel.loehr)
It looks ok, but until the libraries.ent is generated and we can actually get the codebase to compile and tested I can't say for sure.
9. Re: JBoss Third Party Buildruel.loehr Jul 5, 2005 5:24 PM (in response to ruel.loehr)
While working on building I ran across an inconsistency with the old system. In the file modules.ent, from the buildmagic system, the following is defined:
<!-- AOP --> <property name="jboss.aop.root" value="${project.root}/thirdparty/jboss-aop"/> <property name="jboss.aop.lib" value="${jboss.aop.root}/lib"/> <path id="jboss.aop.classpath"> <pathelement path="${jboss.aop.lib}/jboss-aop.jar"/> </path>
This file defines only module properties except for the above. I think this definition should be moved to the libraries.ent file for the following reasons:
1) Consistency
2) If the property exists in the libraries.ent file we can give it the proper value (with the version number in the path) when we generate a new one. If it remains in the modules.ent the property is set and immutable. The build.xml would have to be modified to reference the correct path. (bad)
Are there any reasons why we couldn't or shouldn't do this?
Ruel Loehr
JBoss QA
10. Re: JBoss Third Party Buildstarksm64 Jul 6, 2005 3:09 PM (in response to ruel.loehr)
No reason not to move it. The aop used to be a module in the jboss-4.0 but has now been moved to thirdparty and its classpath should be moved there as well.
11. Re: JBoss Third Party Buildruel.loehr Jul 8, 2005 4:58 PM (in response to ruel.loehr)
Using the thirdparty-build.xml definitions file, a generated libraries.ent file, and a generated thirdparty folder, I have succesfully completed builds using both the 1.4 and 1.5 compiler. The following instructions will execute this functionality.
mkdir test cd test cvs co -r Branch_4_0 jboss-4.0.x cd jboss-4.0 cd build ant -f build-thirdparty.xml generate-lib-file ./build.sh cd output cd jboss-4.0.3RC1 cd bin ./run.sh
The dependencies are downloaded and then the target "generate-lib-file" creates a libraries.ent file which has the correct path information.
I will continue work on validating the build and running the testsuite.
Ruel Loehr
JBoss QA
12. Re: JBoss Third Party Buildryan.campbell Jul 11, 2005 1:29 PM (in response to ruel.loehr)
We should run the testsuite, but the easiest way to verify that the distros are exactly the same is just to compare the output of one with the other:
diff -br jboss-4.0/build/output/ jboss-4.0.x/build/output
13. Re: JBoss Third Party Buildruel.loehr Jul 11, 2005 5:25 PM (in response to ruel.loehr)
The diff yielded excellent results. The structures are the same except for jar files which were constructed by the build, and these differ by only a few bytes (due to time stamps, or version numbers in the manifest files and such).
I do have one task left which needs to be resolved. The testsuite build.xml file uses /tools/etc/libraries.xml for its properties definitions while the rest of the modules use libraries.ent. Upon examination the files look to be relatively the same (libraries.xml is slightly out of date). Could we modify the libraries.xml to include the libraries.ent rather than redefining it? This way we would only have to worry about the maintenance of one file.
14. Re: JBoss Third Party Buildadrian.brock Jul 11, 2005 5:34 PM (in response to ruel.loehr)
Yes please. We should remove libraries.xml and replace it uses with libraries.ent
And do the same with modules.xml -> modules.ent
if you have the time while you are there.


text:
Worldwide, Murcia and Marbella estate agents promotion
Properties are located on Google maps with dynamic and visual information about the environment. All the property details and descriptions translated into the most commonly spoken languages in the world. The top worldwide, Spain, Murcia and Marbella estate agents showcase their exclusive properties in Google maps with description of their surroundings... With the details of the properties translated into many languages. If you want to buy a property... Get accurate information in your language, as well as visual information on local facilities and services. Get in touch with the principal estate agents in Marbella, Murcia and around Spain and the world.
If you are an estate agent in Marbella or your company is is located anywhere in the world, we would like to promote your properties. We can develop a section specifically for your country, region or city with exclusivity for your properties if you require.
We offer for Marbella estate agents and real estate worldwide... All property in all the key languages of the web, translations by experts, Google maps of the area surrounding the property, a guide to the local area, a directory of businesses and services and an introduction about your company...