On Mon, Jul 24, 2006 at 01:38:35PM +0100, Marco Monteiro wrote: > http://common-lisp.net/project/ssc/darcs/spec
As a Darcs non-user, I offer a condensed form of my get'n'build. I'm sure someone will yell if it didn't get the latest: cd /tmp wget http://common-lisp.net/project/ssc/darcs/spec/_darcs/pristine/{format,review,spec}.tex tex review && dvipdf review && xpdf review.pdf & tex spec && dvipdf spec && xpdf spec.pdf & Erm. Not sure how this translates to Windowsese but hopefully you get the idea. A few comments on spec.tex, | All the symbols presented in this document are available as external symbols | in a package named or nicknamed SSC. If the package's primary name is SSC, how is the code to determine which SSC implementation it is using? Is there any reason not to say that SSC shall be a nickname? | [Function] | thread-priority thread | This returns the priority of thread; it is a value between -5 and +5. This can | be changed by using setf. The argument for the setf form must be an integer | between -5 and +5. It is an error if thread is not a thread. | Note that the value you specify with setf might not be the one you get back: | in an implementation that does not support priorities, thread-priority might | always return 0, for example. Since you've already said that the implementation may not return what you setf, is there any reason to restrict priority to integers? It makes the task of mapping priorities (integer 0 100) lossy for no good reason. Any range you choose will fail to match the endpoints of some already-chosen priority systems so in some senses the min/max values aren't important. Getting access to the full power of the underlying code probably is important. You could extend (thread-priority t) to return multiple values, the second being a number indicating the granularity of the underlying code, for the current priority, 10 we don't support priorities, i.e. -5 is equivalent to +5 1 integers 0.1 we mapped (integer 0 100) into (number -5 5) 0 arbitrary precision real numbers (!) A further complication: some scheduling systems might be strongly non-linear. IIRC "nice" is defined to be exponential, but without a "do not ever run if another process wants the CPU" state. If your (integer -5 +5) is defined to be a linear range then the granularity of mapping niceness into that may be high enough to make it useless. I don't know if any thread systems have such a priority scheme. Are these sorts of complications necessary? More generally, is SSC intended to provide minimal support for the basics or will it attempt to unify as many as possible of the available features? | [Function] | signal-state-change state-change-var &key al lp Before I start on this, I should say that I don't think I understand state-change variables: wait-state-change may not be called if you don't hold the mutex, but signal-state-change has support to wake multiple threads? | [...] This function returns an unspecified value. [...] | A spurious wakeup is the unblocking of a thread waiting on a state-change | variable that happens without other thread signalling the state-change variable. | To allow greater flexibility, implementations are allowed to have this behaviour. | Because of this, the state-change variable's predicate must always be checked. This form of the spec requires all code to do the check, even when it isn't needed. This seems wasteful. If signal-state-change were to return true when the wakeup is not spurious, this will require some implementations to do the check at the tail of signal-state-change; but those that don't generate spurious wakeups will cut some code out. In both cases, the spec and implementation have taken on a little extra responsibility, but the users win each time they use it. Moving on to review.tex, [Life cycle] | In Allegro and OpenMCL you can do each of the steps (creating a thread | ob ject, specifying the function to run and start it) separately. Again, the function | that creates the thread ob ject accepts several arguments for configuring the new | thread. In this case, the function that creates the thread does not take a function- | to-run argument. | In Corman and SBCL a thread dies when the function that it was running | returns. In these implementations you can use a thread to run a function one | time. After the functions ends running, the thread cannot run another function. | In the other implementations, a thread can be reset and run another function. In If the spec takes a low-ish common denominator, the resetting functions might be thrown out or ignored. Apart from inconveniencing users of those functions, what is the performance hit likely to be for making and throwing away one thread? If it's small enough, maybe the loss isn't worth the burden of the wrapper library upon other implementations... but if the cost is even suspected to be large then vendors with reset functionality might be reluctant to have it hidden (making your "sales" job that much harder) and their users may stick with the implementation-specific calls (making chunks of code less portable). The alternative is to offer wrapper code which supplies the missing functionality - if this can be done for all implementations. [Interrupting] | [...] Allegro and LispWorks also have without-interrupts macro. In | these two implementations the macro defers these kinds of | interruptions, but also disables other kinds of asynchronous | interrupts, effectively guaranteeing that the body of the macro is | executed without any other thread running, unless the code in body | does something to block or to activate scheduling. That would be a tougher one to provide in a wrapper library... I blocked on the "Special Variables" section. Flushing output so far. Matthew #8-) _______________________________________________ Gardeners mailing list [email protected] http://www.lispniks.com/mailman/listinfo/gardeners
