threads for camelot
play

Threads for Camelot Stephen Gilmore LFCS, University of Edinburgh - PowerPoint PPT Presentation

Threads for Camelot Stephen Gilmore LFCS, University of Edinburgh Presented in Munich, 22nd November 2003 Updated in Edinburgh, 1st December 2003 Threads: review Threads are used to structure programs in order that two (or more) activities


  1. Threads for Camelot Stephen Gilmore LFCS, University of Edinburgh Presented in Munich, 22nd November 2003 Updated in Edinburgh, 1st December 2003

  2. Threads: review Threads are used to structure programs in order that two (or more) activities should appear to take place simultaneously. The execution environment is a single-processor machine, not a multi-processor, so simultaneous activity is only simulated, not genuine. This is concurrent programming, not parallel programming. The aim is not to reduce execution time. Indeed, using threads increases execution time.

  3. Why threads? Since we probably think that our programs don’t run fast enough anyway . . . why do we want threads at all? Mostly threads are used to improve usability of GUIs. The user can do something in one window (say, edit a file) while something else (say, downloading a file over the network) happens in another window “at the same time.” ∗ Most high-level languages provide thread support: Java, Caml, Concurrent Haskell, . . . ∗ Not really at the same time. This is concurrency, not parallelism!

  4. Threads: not just useful, also interesting Threads can be considered along with other advanced language features such as exceptions, first-class continuations, etc. as adding expressive power to a programming language. Thread yielding and resuming can be implemented using call/cc and throw. This is cited as a reason to have first-class continuations in a language. There exist papers on thread implementations and space usage ∗ but not on MRG-style resource bounds for threads, as far as I know. ∗ “Safe-for-space threads for Standard ML”, Biagioni, Cline, Lee, Osaki, Stone, Lisp and Symbolic Computation, 1998

  5. Threads in Java: an example of a clock One simple example of thread usage is a clock, showing the current time and date in a text area in the GUI. This sleeps for a 1/10th of a second and then displays the current date and time in the GUI. Then, repeats forever. It is a relatively simple exercise to implement this in Java using the built-in classes java.lang.Thread , java.util.Date , etc.

  6. / ∗ A simple clock class in Java ∗ / import java.text. ∗ ; import javax.swing. ∗ ; import java.util. ∗ ; public class Clock { public static class Ticker extends Thread { JTextArea ta; SimpleDateFormat formatter; / ∗ The constructor of the class ∗ / public Ticker(JTextArea ta) { this .ta = ta; this .formatter = new SimpleDateFormat (”EEE MMM dd hh:mm:ss yyyy”); }

  7. / ∗ Main method of the thread ∗ / public void run() { / ∗ loop forever ∗ / while ( true ) { try { sleep(100); } catch (InterruptedException e) { } / ∗ Refresh display of time on screen ∗ / ta.setText(formatter.format( new Date())); } } }

  8. / ∗ The main method of the class ∗ / public static void main (String[] args) { JTextArea ta = new JTextArea(); / ∗ Make a new clock object ∗ / Ticker t = new Ticker(ta); / ∗ Start it running as a thread ∗ / t.start (); / ∗ Set up the GUI ∗ / JFrame f = new JFrame(); f.setContentPane(ta); f.setSize(180,60); f. setVisible( true ); } }

  9. Camelot: with object-oriented extensions Camelot now provides language extensions to allow access to Java classes, methods and fields. In addition we can define classes in Camelot. Classes can implement interfaces and may contain fields and methods. Fields may be mutable. Method invocation: o#m() Field access: o#f (Mutable) field update: o#f <- exp

  10. Type-safe casting in Camelot Java provides statically-checked upcasting (towards Object) and dynamically-checked downcasts which may raise java.lang.ClassCastException at run-time. Camelot provides type-safe upcasting (via obj :> Class ) and type-safe downcasting via a typecase construction. Both are statically-checked. ( ∗ Camelot’s typecase construction ∗ ) match myObject with s : > java.lang.String − > s | i : > java.lang.Integer − > i#toString() − > ”no string corresponding to this object” |

  11. Threads in Camelot: an example of a clock Implementing the previous example in Camelot we encounter some problems. ≫ The sleep method may throw a checked exception. Camelot has no exceptions. ≫ The sleep method sleeps for a number of milliseconds specified as a long , not an int . Camelot has no long type.

  12. Simple fixes ≫ We add a sleep function to the Camelot library. This encapsulates the exception handling code. ≫ The sleep can be parameterised by an int which is promoted to a long via Java’s numeric promotion, as usual.

  13. class ticker = ( ∗ The clock class ∗ ) implement java.lang.Runnable field ta : javax.swing.JTextArea field formatter : java.text.SimpleDateFormat method setTextField (f:javax.swing.JTextArea): unit = ta < − f method setFormatting (s: string): unit = formatter < − new java.text.SimpleDateFormat s method run(): unit = let = sleep 100 ( ∗ added sleep function ∗ ) in let now = new java.util.Date() in let s = this#formatter#format now in let = this#ta#setText s in this#run() end

  14. let main args = ( ∗ The main method ∗ ) let frame = new javax.swing.JFrame ”Clock” in let ta = new javax.swing.JTextArea() in let clock = new ticker() in let = clock#setFormatting ”EEE MMM dd hh:mm:ss yyyy” in let = clock#setTextField ta in let clockThread = new java.lang.Thread clock in let = clockThread#start() in let f = new javax.swing.JFrame() in let = f#setContentPane ta in let = f#setSize 180 60 in f#setVisible true

  15. Threads and resources We would like to be able to share data structures and objects between threads. Even in the clock example we share a javax.swing.JTextArea object between the main thread and the clock thread. This then makes problems for the usual Camelot approach to memory management. None of the threads can free an object which they have been passed (because another thread might have a reference to it).

  16. Multi-threaded Camelot We want to be able to use threads in a way which “ plays nice ” with Camelot memory management. ≫ Single-threaded programs must have the same memory usage as presently. ≫ Multi-threaded programs should be able to free and recycle addresses. ≫ Threads should be able to accept objects as parameters and return objects as results. ≫ Objects should be shared, not cloned (“cloned” ≡ copied by deep copy ≡ passed by value).

  17. Reminder: using the free list Camelot uses a uniform representation of data types, thus the storage occupied by one object can be freed and re-used by another object, even one of another class. ( ∗ summing the elements of an int list ∗ ) let rec sumList lst = match lst with [ ] − > 0 | ( h::t)@ − > h + sumList t ( ∗ obj@ == free(obj) ∗ ) In this example, the cons cells of a list are freed and may be reused to, say, build a binary tree.

  18. Multi-threaded Camelot—how to free In moving from one to multiple threads a key question with respect to memory usage is: 1. should the free list of storage which can be reused be a single static instance shared across all threads; or 2. should each thread separately maintain their own local instance of the free list?

  19. Free lists (1): a single shared instance In this case the accessor methods for the free list must be synchronised in order for data structures not to become disordered by concurrent write operations. Synchronisation incurs an overhead of locking and unlocking the parent of the field when entering and leaving a critical region. This imposes a penalty on program run-time.

  20. Free lists (2): multiple, private free lists In this there is no requirement for access to the free list to be synchronised; each thread has its own free list. But, the free memory on each free list is private, and not shared. This means that there will be times when one thread allocates memory (with a Java new instruction) while another thread has unused memory on its local free list. This would lead to programs typically using more memory overall.

  21. Free lists (2b): multiple, private weak free lists A variation on (2) would be to use private, unsynchronised free lists implemented using weak pointers. Weak pointers are pointers to objects which, by themselves, are not enough to keep the object alive. Used for implementing caches, or secondary index data structures. (Caml/Moscow ML: Weak structure. Java: java.lang.ref.WeakReference ). Disadvantage: J2ME does not implement the class java.lang.ref.WeakReference .

  22. Conclusion: how to free Use a single, shared, synchronised free list. Our programs will take longer than their optimum run-time but memory performance will be improved.

  23. Multi-threaded Camelot: when to free We have the remaining problem of knowing when to free an object. At the workshop we discussed reference counting but concluded that it would impact badly on the byte code logic. Having rejected that, we decided that threads in Camelot should never free shared (Java) objects, only locally-allocated Camelot ones.

  24. Discussion: implications for the bytecode logic and formalisation in Isabelle Hopefully none, or at least nothing severe. As before, we have a single free list represented somehow. No proposal to represent synchronised access to the free list formally. This would be a mutual exclusion algorithm formalisation exercise done many times previously by others. Off the MRG radar.

Recommend


More recommend