df007f1e82e7f5d13ef2903a9f6c2c7e4b926726
[cacao.git] / src / threads / lock.cpp
1 /* src/threads/lock.cpp - lock implementation
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/time.h>
33
34 #include "vm/types.h"
35
36 #include "mm/memory.hpp"
37
38 #include "native/llni.h"
39
40 #include "threads/atomic.hpp"
41 #include "threads/lock.hpp"
42 #include "threads/mutex.hpp"
43 #include "threads/threadlist.hpp"
44 #include "threads/thread.hpp"
45
46 #include "toolbox/list.hpp"
47
48 #include "vm/exceptions.hpp"
49 #include "vm/finalizer.hpp"
50 #include "vm/global.h"
51 #include "vm/options.h"
52 #include "vm/string.hpp"
53 #include "vm/vm.hpp"
54
55 #if defined(ENABLE_STATISTICS)
56 # include "vm/statistics.h"
57 #endif
58
59 #if defined(ENABLE_VMLOG)
60 #include <vmlog_cacao.h>
61 #endif
62
63 #if defined(ENABLE_JVMTI)
64 #include "native/jvmti/cacaodbg.h"
65 #endif
66
67 #if defined(ENABLE_GC_BOEHM)
68 # include "mm/boehm-gc/include/gc.h"
69 #endif
70
71
72 /* debug **********************************************************************/
73
74 #if !defined(NDEBUG)
75 # define DEBUGLOCKS(format) \
76     do { \
77         if (opt_DebugLocks) { \
78             log_println format; \
79         } \
80     } while (0)
81 #else
82 # define DEBUGLOCKS(format)
83 #endif
84
85
86 /******************************************************************************/
87 /* MACROS                                                                     */
88 /******************************************************************************/
89
90 /* number of lock records in the first pool allocated for a thread */
91 #define LOCK_INITIAL_LOCK_RECORDS 8
92
93 #define LOCK_INITIAL_HASHTABLE_SIZE  1613  /* a prime in the middle between 1024 and 2048 */
94
95
96 /******************************************************************************/
97 /* MACROS FOR THIN/FAT LOCKS                                                  */
98 /******************************************************************************/
99
100 /* We use a variant of the tasuki locks described in the paper
101  *     
102  *     Tamiya Onodera, Kiyokuni Kawachiya
103  *     A Study of Locking Objects with Bimodal Fields
104  *     Proceedings of the ACM OOPSLA '99, pp. 223-237
105  *     1999
106  *
107  * The underlying thin locks are a variant of the thin locks described in
108  * 
109  *     Bacon, Konuru, Murthy, Serrano
110  *     Thin Locks: Featherweight Synchronization for Java
111  *         Proceedings of the ACM Conference on Programming Language Design and 
112  *         Implementation (Montreal, Canada), SIGPLAN Notices volume 33, number 6,
113  *         June 1998
114  *
115  * In thin lock mode the lockword looks like this:
116  *
117  *     ,----------------------,-----------,---,
118  *     |      thread ID       |   count   | 0 |
119  *     `----------------------'-----------'---'
120  *
121  *     thread ID......the 'index' of the owning thread, or 0
122  *     count..........number of times the lock has been entered minus 1
123  *     0..............the shape bit is 0 in thin lock mode
124  *
125  * In fat lock mode it is basically a lock_record_t *:
126  *
127  *     ,----------------------------------,---,
128  *     |    lock_record_t * (without LSB) | 1 |
129  *     `----------------------------------'---'
130  *
131  *     1..............the shape bit is 1 in fat lock mode
132  */
133
134 /* global variables ***********************************************************/
135
136 /* hashtable mapping objects to lock records */
137 static lock_hashtable_t lock_hashtable;
138
139
140 /******************************************************************************/
141 /* PROTOTYPES                                                                 */
142 /******************************************************************************/
143
144 static void lock_hashtable_init(void);
145
146 static inline Lockword* lock_lockword_get(java_handle_t* o);
147 static void lock_record_enter(threadobject *t, lock_record_t *lr);
148 static void lock_record_exit(threadobject *t, lock_record_t *lr);
149 static bool lock_record_wait(threadobject *t, lock_record_t *lr, s8 millis, s4 nanos);
150 static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one);
151
152
153 /*============================================================================*/
154 /* INITIALIZATION OF DATA STRUCTURES                                          */
155 /*============================================================================*/
156
157
158 /* lock_init *******************************************************************
159
160    Initialize global data for locking.
161
162 *******************************************************************************/
163
164 void lock_init(void)
165 {
166         /* initialize lock hashtable */
167
168         lock_hashtable_init();
169
170 #if defined(ENABLE_VMLOG)
171         vmlog_cacao_init_lock();
172 #endif
173 }
174
175
176 /* lock_record_new *************************************************************
177
178    Allocate a lock record.
179
180 *******************************************************************************/
181
182 static lock_record_t *lock_record_new(void)
183 {
184         lock_record_t *lr;
185
186         /* allocate the data structure on the C heap */
187
188         lr = NEW(lock_record_t);
189
190 #if defined(ENABLE_STATISTICS)
191         if (opt_stat)
192                 size_lock_record += sizeof(lock_record_t);
193 #endif
194
195         /* initialize the members */
196
197         lr->object  = NULL;
198         lr->owner   = NULL;
199         lr->count   = 0;
200         lr->waiters = new List<threadobject*>();
201
202 #if defined(ENABLE_GC_CACAO)
203         /* register the lock object as weak reference with the GC */
204
205         gc_weakreference_register(&(lr->object), GC_REFTYPE_LOCKRECORD);
206 #endif
207
208         // Initialize the mutex.
209         lr->mutex = new Mutex();
210
211         DEBUGLOCKS(("[lock_record_new   : lr=%p]", (void *) lr));
212
213         return lr;
214 }
215
216
217 /* lock_record_free ************************************************************
218
219    Free a lock record.
220
221    IN:
222        lr....lock record to free
223
224 *******************************************************************************/
225
226 static void lock_record_free(lock_record_t *lr)
227 {
228         DEBUGLOCKS(("[lock_record_free  : lr=%p]", (void *) lr));
229
230         // Destroy the mutex.
231         delete lr->mutex;
232
233 #if defined(ENABLE_GC_CACAO)
234         /* unregister the lock object reference with the GC */
235
236         gc_weakreference_unregister(&(lr->object));
237 #endif
238
239         // Free the waiters list.
240         delete lr->waiters;
241
242         /* Free the data structure. */
243
244         FREE(lr, lock_record_t);
245
246 #if defined(ENABLE_STATISTICS)
247         if (opt_stat)
248                 size_lock_record -= sizeof(lock_record_t);
249 #endif
250 }
251
252
253 /*============================================================================*/
254 /* HASHTABLE MAPPING OBJECTS TO LOCK RECORDS                                  */
255 /*============================================================================*/
256
257 /* lock_hashtable_init *********************************************************
258
259    Initialize the global hashtable mapping objects to lock records.
260
261 *******************************************************************************/
262
263 static void lock_hashtable_init(void)
264 {
265         lock_hashtable.mutex   = new Mutex();
266
267         lock_hashtable.size    = LOCK_INITIAL_HASHTABLE_SIZE;
268         lock_hashtable.entries = 0;
269         lock_hashtable.ptr     = MNEW(lock_record_t *, lock_hashtable.size);
270
271 #if defined(ENABLE_STATISTICS)
272         if (opt_stat)
273                 size_lock_hashtable += sizeof(lock_record_t *) * lock_hashtable.size;
274 #endif
275
276         MZERO(lock_hashtable.ptr, lock_record_t *, lock_hashtable.size);
277 }
278
279
280 /* lock_hashtable_grow *********************************************************
281
282    Grow the lock record hashtable to about twice its current size and
283    rehash the entries.
284
285 *******************************************************************************/
286
287 /* must be called with hashtable mutex locked */
288 static void lock_hashtable_grow(void)
289 {
290         u4 oldsize;
291         u4 newsize;
292         lock_record_t **oldtable;
293         lock_record_t **newtable;
294         lock_record_t *lr;
295         lock_record_t *next;
296         u4 i;
297         u4 h;
298         u4 newslot;
299
300         /* allocate a new table */
301
302         oldsize = lock_hashtable.size;
303         newsize = oldsize*2 + 1; /* XXX should use prime numbers */
304
305         DEBUGLOCKS(("growing lock hashtable to size %d", newsize));
306
307         oldtable = lock_hashtable.ptr;
308         newtable = MNEW(lock_record_t *, newsize);
309
310 #if defined(ENABLE_STATISTICS)
311         if (opt_stat)
312                 size_lock_hashtable += sizeof(lock_record_t *) * newsize;
313 #endif
314
315         MZERO(newtable, lock_record_t *, newsize);
316
317         /* rehash the entries */
318
319         for (i = 0; i < oldsize; i++) {
320                 lr = oldtable[i];
321                 while (lr) {
322                         next = lr->hashlink;
323
324                         h = heap_hashcode(lr->object);
325                         newslot = h % newsize;
326
327                         lr->hashlink = newtable[newslot];
328                         newtable[newslot] = lr;
329
330                         lr = next;
331                 }
332         }
333
334         /* replace the old table */
335
336         lock_hashtable.ptr  = newtable;
337         lock_hashtable.size = newsize;
338
339         MFREE(oldtable, lock_record_t *, oldsize);
340
341 #if defined(ENABLE_STATISTICS)
342         if (opt_stat)
343                 size_lock_hashtable -= sizeof(lock_record_t *) * oldsize;
344 #endif
345 }
346
347
348 /* lock_hashtable_cleanup ******************************************************
349
350    Removes (and frees) lock records which have a cleared object reference
351    from the hashtable. The locked object was reclaimed by the GC.
352
353 *******************************************************************************/
354
355 #if defined(ENABLE_GC_CACAO)
356 void lock_hashtable_cleanup(void)
357 {
358         threadobject  *t;
359         lock_record_t *lr;
360         lock_record_t *prev;
361         lock_record_t *next;
362         int i;
363
364         t = THREADOBJECT;
365
366         /* lock the hashtable */
367
368         Mutex_lock(lock_hashtable.mutex);
369
370         /* search the hashtable for cleared references */
371
372         for (i = 0; i < lock_hashtable.size; i++) {
373                 lr = lock_hashtable.ptr[i];
374                 prev = NULL;
375
376                 while (lr) {
377                         next = lr->hashlink;
378
379                         /* remove lock records with cleared references */
380
381                         if (lr->object == NULL) {
382
383                                 /* unlink the lock record from the hashtable */
384
385                                 if (prev == NULL)
386                                         lock_hashtable.ptr[i] = next;
387                                 else
388                                         prev->hashlink = next;
389
390                                 /* free the lock record */
391
392                                 lock_record_free(lr);
393
394                         } else {
395                                 prev = lr;
396                         }
397
398                         lr = next;
399                 }
400         }
401
402         /* unlock the hashtable */
403
404         Mutex_unlock(lock_hashtable.mutex);
405 }
406 #endif
407
408
409 /* lock_hashtable_get **********************************************************
410
411    Find the lock record for the given object.  If it does not exists,
412    yet, create it and enter it in the hashtable.
413
414    IN:
415           o....the object to look up
416
417    RETURN VALUE:
418       the lock record to use for this object
419
420 *******************************************************************************/
421
422 #if defined(ENABLE_GC_BOEHM)
423 static void lock_record_finalizer(void *object, void *p);
424 #endif
425
426 static lock_record_t *lock_hashtable_get(java_handle_t* o)
427 {
428         // This function is inside a critical section.
429         GCCriticalSection cs;
430
431         u4             slot;
432         lock_record_t *lr;
433
434         Lockword* lockword = lock_lockword_get(o);
435
436         if (lockword->is_fat_lock())
437                 return lockword->get_fat_lock();
438
439         // Lock the hashtable.
440         lock_hashtable.mutex->lock();
441
442         /* lookup the lock record in the hashtable */
443
444         slot = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
445         lr   = lock_hashtable.ptr[slot];
446
447         for (; lr != NULL; lr = lr->hashlink) {
448                 if (lr->object == LLNI_DIRECT(o))
449                         break;
450         }
451
452         if (lr == NULL) {
453                 /* not found, we must create a new one */
454
455                 lr = lock_record_new();
456
457                 lr->object = LLNI_DIRECT(o);
458
459 #if defined(ENABLE_GC_BOEHM)
460                 /* register new finalizer to clean up the lock record */
461
462                 GC_REGISTER_FINALIZER(LLNI_DIRECT(o), lock_record_finalizer, 0, 0, 0);
463 #endif
464
465                 /* enter it in the hashtable */
466
467                 lr->hashlink             = lock_hashtable.ptr[slot];
468                 lock_hashtable.ptr[slot] = lr;
469                 lock_hashtable.entries++;
470
471                 /* check whether the hash should grow */
472
473                 if (lock_hashtable.entries * 3 > lock_hashtable.size * 4) {
474                         lock_hashtable_grow();
475                 }
476         }
477
478         // Unlock the hashtable.
479         lock_hashtable.mutex->unlock();
480
481         /* return the new lock record */
482
483         return lr;
484 }
485
486
487 /* lock_hashtable_remove *******************************************************
488
489    Remove the lock record for the given object from the hashtable
490    and free it afterwards.
491
492    IN:
493        t....the current thread
494        o....the object to look up
495
496 *******************************************************************************/
497
498 static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
499 {
500         lock_record_t *lr;
501         u4             slot;
502         lock_record_t *tmplr;
503
504         // Lock the hashtable.
505         lock_hashtable.mutex->lock();
506
507         /* get lock record */
508
509         Lockword* lockword = lock_lockword_get(o);
510
511         // Sanity check.
512         assert(lockword->is_fat_lock());
513
514         lr = lockword->get_fat_lock();
515
516         /* remove the lock-record from the hashtable */
517
518         slot  = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
519         tmplr = lock_hashtable.ptr[slot];
520
521         if (tmplr == lr) {
522                 /* special handling if it's the first in the chain */
523
524                 lock_hashtable.ptr[slot] = lr->hashlink;
525         }
526         else {
527                 for (; tmplr != NULL; tmplr = tmplr->hashlink) {
528                         if (tmplr->hashlink == lr) {
529                                 tmplr->hashlink = lr->hashlink;
530                                 break;
531                         }
532                 }
533
534                 assert(tmplr != NULL);
535         }
536
537         /* decrease entry count */
538
539         lock_hashtable.entries--;
540
541         // Unlock the hashtable.
542         lock_hashtable.mutex->unlock();
543
544         /* free the lock record */
545
546         lock_record_free(lr);
547 }
548
549
550 /* lock_record_finalizer *******************************************************
551
552    XXX Remove me for exact GC.
553
554 *******************************************************************************/
555
556 static void lock_record_finalizer(void *object, void *p)
557 {
558         java_handle_t *o;
559         classinfo     *c;
560
561         o = (java_handle_t *) object;
562
563 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
564         /* XXX this is only a dirty hack to make Boehm work with handles */
565
566         o = LLNI_WRAP((java_object_t *) o);
567 #endif
568
569         LLNI_class_get(o, c);
570
571 #if !defined(NDEBUG)
572         if (opt_DebugFinalizer) {
573                 log_start();
574                 log_print("[finalizer lockrecord: o=%p p=%p class=", object, p);
575                 class_print(c);
576                 log_print("]");
577                 log_finish();
578         }
579 #endif
580
581         /* check for a finalizer function */
582
583         if (c->finalizer != NULL)
584                 finalizer_run(object, p);
585
586         /* remove the lock-record entry from the hashtable and free it */
587
588         lock_hashtable_remove(THREADOBJECT, o);
589 }
590
591
592 /*============================================================================*/
593 /* LOCKING ALGORITHM                                                          */
594 /*============================================================================*/
595
596
597 /* lock_lockword_get ***********************************************************
598
599    Get the lockword for the given object.
600
601    IN:
602       o............the object
603
604 *******************************************************************************/
605
606 static inline Lockword* lock_lockword_get(java_handle_t* o)
607 {
608 #if defined(ENABLE_GC_CACAO)
609         // Sanity check.
610         assert(GCCriticalSection::inside() == true);
611 #endif
612
613         return &(LLNI_DIRECT(o)->lockword);
614 }
615
616
617 /* lock_record_enter ***********************************************************
618
619    Enter the lock represented by the given lock record.
620
621    IN:
622       t.................the current thread
623           lr................the lock record
624
625 *******************************************************************************/
626
627 static inline void lock_record_enter(threadobject *t, lock_record_t *lr)
628 {
629         lr->mutex->lock();
630         lr->owner = t;
631 }
632
633
634 /* lock_record_exit ************************************************************
635
636    Release the lock represented by the given lock record.
637
638    IN:
639       t.................the current thread
640           lr................the lock record
641
642    PRE-CONDITION:
643       The current thread must own the lock represented by this lock record.
644           This is NOT checked by this function!
645
646 *******************************************************************************/
647
648 static inline void lock_record_exit(threadobject *t, lock_record_t *lr)
649 {
650         lr->owner = NULL;
651         lr->mutex->unlock();
652 }
653
654
655 /* lock_inflate ****************************************************************
656
657    Inflate the lock of the given object. This may only be called by the
658    owner of the monitor of the object.
659
660    IN:
661           o............the object of which to inflate the lock
662           lr...........the lock record to install. The current thread must
663                        own the lock of this lock record!
664
665    PRE-CONDITION:
666       The current thread must be the owner of this object's monitor AND
667           of the lock record's lock!
668
669 *******************************************************************************/
670
671 static void lock_inflate(java_handle_t *o, lock_record_t *lr)
672 {
673         Lockword* lockword = lock_lockword_get(o);
674         lockword->inflate(lr);
675 }
676
677
678 /* sable_flc_waiting ***********************************************************
679
680    Enqueue the current thread on another thread's FLC list. The function
681    blocks until the lock has been inflated by the owning thread.
682
683    The algorithm used to be an almost literal copy from SableVM. The
684    superfluous list traversal in the waiting loop has been removed since,
685    though.
686
687    IN:
688           lockword.....the object's lockword as seen at the first locking attempt
689           t............the current thread
690           o............the object of which to enter the monitor
691
692 *******************************************************************************/
693
694 static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t *o)
695 {
696         int32_t index;
697         threadobject *t_other;
698         int old_flc;
699
700         index = lockword->get_thin_lock_thread_index();
701         t_other = ThreadList::get_thread_by_index(index);
702
703         // The lockword could have changed during our way here.  If the
704         // thread index is zero, the lock got unlocked and we simply
705         // return.
706         if (t_other == NULL)
707 /*              failure, TODO: add statistics */
708                 return;
709
710         t_other->flc_lock->lock();
711         old_flc = t_other->flc_bit;
712         t_other->flc_bit = true;
713
714         DEBUGLOCKS(("thread %d set flc bit for lock-holding thread %d", t->index, t_other->index));
715
716         // Set FLC bit first, then read the lockword again.
717         Atomic::memory_barrier();
718
719         lockword = lock_lockword_get(o);
720
721         /* Lockword is still the way it was seen before */
722         if (lockword->is_thin_lock() && (lockword->get_thin_lock_thread_index() == index))
723         {
724                 threadobject *f;
725                 /* Add tuple (t, o) to the other thread's FLC list */
726                 t->flc_object = o;
727                 t->flc_next = t_other->flc_list;
728                 t_other->flc_list = t;
729                 if (t->flc_next == 0)
730                         t_other->flc_tail = t;
731                 f = t_other->flc_tail;
732
733                 // The other thread will clear flc_object.
734                 while (t->flc_object)
735                 {
736                         // We are not cleared yet -- the other thread cannot have seen
737                         // the FLC bit yet.
738                         assert(t_other->flc_bit);
739
740                         // Wait until another thread sees the flc bit and notifies
741                         // us of unlocking.
742                         t->flc_cond->wait(t_other->flc_lock);
743                 }
744
745                 t->flc_next = NULL;
746         }
747         else
748                 t_other->flc_bit = old_flc;
749
750         t_other->flc_lock->unlock();
751 }
752
753 /* notify_flc_waiters **********************************************************
754
755    Traverse the thread's FLC list and inflate all corresponding locks. Notify
756    the associated threads as well.
757
758    IN:
759           t............the current thread
760           o............the object currently being unlocked
761
762 *******************************************************************************/
763
764 static void notify_flc_waiters(threadobject *t, java_handle_t *o)
765 {
766         threadobject *current;
767
768         t->flc_lock->lock();
769
770         current = t->flc_list;
771         while (current)
772         {
773                 if (current->flc_object != o)
774                 {
775                         /* The object has to be inflated so the other threads can properly
776                            block on it. */
777
778                         // Only if not already inflated.
779                         Lockword* lockword = lock_lockword_get(current->flc_object);
780                         if (lockword->is_thin_lock()) {
781                                 lock_record_t *lr = lock_hashtable_get(current->flc_object);
782                                 lock_record_enter(t, lr);
783
784                                 DEBUGLOCKS(("thread %d inflating lock of %p to lr %p",
785                                                         t->index, (void*) current->flc_object, (void*) lr));
786
787                                 lock_inflate(current->flc_object, lr);
788                         }
789                 }
790
791                 // Wake the waiting threads.
792                 current->flc_cond->broadcast();
793                 current->flc_object = NULL;
794
795                 current = current->flc_next;
796         }
797
798         t->flc_list = NULL;
799         t->flc_bit = false;
800
801         t->flc_lock->unlock();
802 }
803
804 /* lock_monitor_enter **********************************************************
805
806    Acquire the monitor of the given object. If the current thread already
807    owns the monitor, the lock counter is simply increased.
808
809    This function blocks until it can acquire the monitor.
810
811    IN:
812       t............the current thread
813           o............the object of which to enter the monitor
814
815    RETURN VALUE:
816       true.........the lock has been successfully acquired
817           false........an exception has been thrown
818
819 *******************************************************************************/
820
821 bool lock_monitor_enter(java_handle_t *o)
822 {
823         // This function is inside a critical section.
824         GCCriticalSection cs;
825
826         if (o == NULL) {
827                 exceptions_throw_nullpointerexception();
828                 return false;
829         }
830
831         threadobject* t = thread_get_current();
832
833         uintptr_t thinlock = t->thinlock;
834
835 retry:
836         // Most common case: try to thin-lock an unlocked object.
837         Lockword* lockword = lock_lockword_get(o);
838         bool result = lockword->lock(thinlock);
839
840         if (result == true) {
841                 // Success, we locked it.
842                 // NOTE: The Java Memory Model requires an instruction barrier
843                 // here (because of the CAS above).
844                 Atomic::instruction_barrier();
845                 return true;
846         }
847
848         // Next common case: recursive lock with small recursion count.
849         // NOTE: We don't have to worry about stale values here, as any
850         // stale value will indicate another thread holding the lock (or
851         // an inflated lock).
852         if (lockword->get_thin_lock_without_count() == thinlock) {
853                 // We own this monitor.  Check the current recursion count.
854                 if (lockword->is_max_thin_lock_count() == false) {
855                         // The recursion count is low enough.
856                         lockword->increase_thin_lock_count();
857
858                         // Success, we locked it.
859                         return true;
860                 }
861                 else {
862                         // Recursion count overflow.
863                         lock_record_t* lr = lock_hashtable_get(o);
864                         lock_record_enter(t, lr);
865                         lock_inflate(o, lr);
866                         lr->count++;
867
868                         notify_flc_waiters(t, o);
869
870                         return true;
871                 }
872         }
873
874         // The lock is either contented or fat.
875         if (lockword->is_fat_lock()) {
876                 lock_record_t* lr = lockword->get_fat_lock();
877
878                 // Check for recursive entering.
879                 if (lr->owner == t) {
880                         lr->count++;
881                         return true;
882                 }
883
884                 // Acquire the mutex of the lock record.
885                 lock_record_enter(t, lr);
886
887                 // Sanity check.
888                 assert(lr->count == 0);
889                 return true;
890         }
891
892         /****** inflation path ******/
893
894 #if defined(ENABLE_JVMTI)
895         /* Monitor Contended Enter */
896         jvmti_MonitorContendedEntering(false, o);
897 #endif
898
899         sable_flc_waiting(lockword, t, o);
900
901 #if defined(ENABLE_JVMTI)
902         /* Monitor Contended Entered */
903         jvmti_MonitorContendedEntering(true, o);
904 #endif
905         goto retry;
906 }
907
908
909 /* lock_monitor_exit ***********************************************************
910
911    Decrement the counter of a (currently owned) monitor. If the counter
912    reaches zero, release the monitor.
913
914    If the current thread is not the owner of the monitor, an 
915    IllegalMonitorState exception is thrown.
916
917    IN:
918       t............the current thread
919           o............the object of which to exit the monitor
920
921    RETURN VALUE:
922       true.........everything ok,
923           false........an exception has been thrown
924
925 *******************************************************************************/
926
927 bool lock_monitor_exit(java_handle_t* o)
928 {
929         // This function is inside a critical section.
930         GCCriticalSection cs;
931
932         if (o == NULL) {
933                 exceptions_throw_nullpointerexception();
934                 return false;
935         }
936
937         threadobject* t = thread_get_current();
938
939         uintptr_t thinlock = t->thinlock;
940
941         // We don't have to worry about stale values here, as any stale
942         // value will indicate that we don't own the lock.
943         Lockword* lockword = lock_lockword_get(o);
944
945         // Most common case: we release a thin lock that we hold once.
946         if (lockword->get_thin_lock() == thinlock) {
947                 // Memory barrier for Java Memory Model.
948                 Atomic::write_memory_barrier();
949                 lockword->unlock();
950                 // Memory barrier for thin locking.
951                 Atomic::memory_barrier();
952
953                 /* check if there has been a flat lock contention on this object */
954
955                 if (t->flc_bit) {
956                         DEBUGLOCKS(("thread %d saw flc bit", t->index));
957
958                         /* there has been a contention on this thin lock */
959                         notify_flc_waiters(t, o);
960                 }
961
962                 return true;
963         }
964
965         // Next common case: we release a recursive lock, count > 0.
966         if (lockword->get_thin_lock_without_count() == thinlock) {
967                 lockword->decrease_thin_lock_count();
968                 return true;
969         }
970
971         // Either the lock is fat, or we don't hold it at all.
972         if (lockword->is_fat_lock()) {
973                 lock_record_t* lr = lockword->get_fat_lock();
974
975                 // Check if we own this monitor.
976                 // NOTE: We don't have to worry about stale values here, as
977                 // any stale value will be != t and thus fail this check.
978                 if (lr->owner != t) {
979                         exceptions_throw_illegalmonitorstateexception();
980                         return false;
981                 }
982
983                 /* { the current thread `t` owns the lock record `lr` on object `o` } */
984
985                 if (lr->count != 0) {
986                         // We had locked this one recursively.  Just decrement, it
987                         // will still be locked.
988                         lr->count--;
989                         return true;
990                 }
991
992                 // Unlock this lock record.
993                 lock_record_exit(t, lr);
994                 return true;
995         }
996
997         // Legal thin lock cases have been handled above, so this is an
998         // error.
999         exceptions_throw_illegalmonitorstateexception();
1000
1001         return false;
1002 }
1003
1004
1005 /* lock_record_add_waiter ******************************************************
1006
1007    Add a thread to the list of waiting threads of a lock record.
1008
1009    IN:
1010       lr...........the lock record
1011       thread.......the thread to add
1012
1013 *******************************************************************************/
1014
1015 static void lock_record_add_waiter(lock_record_t *lr, threadobject* t)
1016 {
1017         // Add the thread as last entry to waiters list.
1018         lr->waiters->push_back(t);
1019
1020 #if defined(ENABLE_STATISTICS)
1021         if (opt_stat)
1022                 size_lock_waiter += sizeof(threadobject*);
1023 #endif
1024 }
1025
1026
1027 /* lock_record_remove_waiter ***************************************************
1028
1029    Remove a thread from the list of waiting threads of a lock record.
1030
1031    IN:
1032       lr...........the lock record
1033       t............the current thread
1034
1035    PRE-CONDITION:
1036       The current thread must be the owner of the lock record.
1037    
1038 *******************************************************************************/
1039
1040 static void lock_record_remove_waiter(lock_record_t *lr, threadobject* t)
1041 {
1042         // Remove the thread from the waiters.
1043         lr->waiters->remove(t);
1044
1045 #if defined(ENABLE_STATISTICS)
1046         if (opt_stat)
1047                 size_lock_waiter -= sizeof(threadobject*);
1048 #endif
1049 }
1050
1051
1052 /* lock_record_wait ************************************************************
1053
1054    Wait on a lock record for a given (maximum) amount of time.
1055
1056    IN:
1057       t............the current thread
1058           lr...........the lock record
1059           millis.......milliseconds of timeout
1060           nanos........nanoseconds of timeout
1061
1062    RETURN VALUE:
1063       true.........we have been interrupted,
1064       false........everything ok
1065
1066    PRE-CONDITION:
1067       The current thread must be the owner of the lock record.
1068           This is NOT checked by this function!
1069    
1070 *******************************************************************************/
1071
1072 static bool lock_record_wait(threadobject *thread, lock_record_t *lr, s8 millis, s4 nanos)
1073 {
1074         s4   lockcount;
1075         bool wasinterrupted = false;
1076
1077         DEBUGLOCKS(("[lock_record_wait  : lr=%p, t=%p, millis=%lld, nanos=%d]",
1078                                 lr, thread, millis, nanos));
1079
1080         /* { the thread t owns the fat lock record lr on the object o } */
1081
1082         /* register us as waiter for this object */
1083
1084         lock_record_add_waiter(lr, thread);
1085
1086         /* remember the old lock count */
1087
1088         lockcount = lr->count;
1089
1090         /* unlock this record */
1091
1092         lr->count = 0;
1093         lock_record_exit(thread, lr);
1094
1095         /* wait until notified/interrupted/timed out */
1096
1097         threads_wait_with_timeout_relative(thread, millis, nanos);
1098
1099         /* re-enter the monitor */
1100
1101         lock_record_enter(thread, lr);
1102
1103         /* remove us from the list of waiting threads */
1104
1105         lock_record_remove_waiter(lr, thread);
1106
1107         /* restore the old lock count */
1108
1109         lr->count = lockcount;
1110
1111         /* We can only be signaled OR interrupted, not both. If both flags
1112            are set, reset only signaled and leave the thread in
1113            interrupted state. Otherwise, clear both. */
1114
1115         if (!thread->signaled) {
1116                 wasinterrupted = thread->interrupted;
1117                 thread->interrupted = false;
1118         }
1119
1120         thread->signaled = false;
1121
1122         /* return if we have been interrupted */
1123
1124         return wasinterrupted;
1125 }
1126
1127
1128 /* lock_monitor_wait ***********************************************************
1129
1130    Wait on an object for a given (maximum) amount of time.
1131
1132    IN:
1133       t............the current thread
1134           o............the object
1135           millis.......milliseconds of timeout
1136           nanos........nanoseconds of timeout
1137
1138    PRE-CONDITION:
1139       The current thread must be the owner of the object's monitor.
1140    
1141 *******************************************************************************/
1142
1143 static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 nanos)
1144 {
1145         lock_record_t *lr;
1146
1147         Lockword* lockword = lock_lockword_get(o);
1148
1149         // Check if we own this monitor.
1150         // NOTE: We don't have to worry about stale values here, as any
1151         // stale value will fail this check.
1152         if (lockword->is_fat_lock()) {
1153                 lr = lockword->get_fat_lock();
1154
1155                 if (lr->owner != t) {
1156                         exceptions_throw_illegalmonitorstateexception();
1157                         return;
1158                 }
1159         }
1160         else {
1161                 // It's a thin lock.
1162                 if (lockword->get_thin_lock_without_count() != t->thinlock) {
1163                         exceptions_throw_illegalmonitorstateexception();
1164                         return;
1165                 }
1166
1167                 // Get the lock-record.
1168                 lr = lock_hashtable_get(o);
1169                 lock_record_enter(t, lr);
1170
1171                 // Inflate this lock.
1172                 lockword->inflate(lr);
1173
1174                 notify_flc_waiters(t, o);
1175         }
1176
1177         /* { the thread t owns the fat lock record lr on the object o } */
1178
1179         if (lock_record_wait(t, lr, millis, nanos))
1180                 exceptions_throw_interruptedexception();
1181 }
1182
1183
1184 /* lock_record_notify **********************************************************
1185
1186    Notify one thread or all threads waiting on the given lock record.
1187
1188    IN:
1189       t............the current thread
1190           lr...........the lock record
1191           one..........if true, only notify one thread
1192
1193    PRE-CONDITION:
1194       The current thread must be the owner of the lock record.
1195           This is NOT checked by this function!
1196    
1197 *******************************************************************************/
1198
1199 static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
1200 {
1201 #if defined(ENABLE_GC_CACAO)
1202         // Sanity check.
1203         assert(GCCriticalSection::inside() == false);
1204 #endif
1205
1206         // { The thread t owns the fat lock record lr on the object o }
1207
1208         for (List<threadobject*>::iterator it = lr->waiters->begin(); it != lr->waiters->end(); it++) {
1209                 threadobject* waiter = *it;
1210
1211                 // We must skip threads which have already been notified. They
1212                 // will remove themselves from the list.
1213                 if (waiter->signaled)
1214                         continue;
1215
1216                 // Enter the wait-mutex.
1217                 waiter->waitmutex->lock();
1218
1219                 DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, one=%d]", lr, t, waiter, one));
1220
1221                 // Signal the waiter.
1222                 waiter->waitcond->signal();
1223
1224                 // Mark the thread as signaled.
1225                 waiter->signaled = true;
1226
1227                 // Leave the wait-mutex.
1228                 waiter->waitmutex->unlock();
1229
1230                 // If we should only wake one thread, we are done.
1231                 if (one)
1232                         break;
1233         }
1234 }
1235
1236
1237 /* lock_monitor_notify *********************************************************
1238
1239    Notify one thread or all threads waiting on the given object.
1240
1241    IN:
1242       t............the current thread
1243           o............the object
1244           one..........if true, only notify one thread
1245
1246    PRE-CONDITION:
1247       The current thread must be the owner of the object's monitor.
1248    
1249 *******************************************************************************/
1250
1251 static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one)
1252 {
1253         lock_record_t* lr = NULL;
1254
1255         {
1256                 // This scope is inside a critical section.
1257                 GCCriticalSection cs;
1258
1259                 Lockword* lockword = lock_lockword_get(o);
1260
1261                 // Check if we own this monitor.
1262                 // NOTE: We don't have to worry about stale values here, as any
1263                 // stale value will fail this check.
1264
1265                 if (lockword->is_fat_lock()) {
1266                         lr = lockword->get_fat_lock();
1267
1268                         if (lr->owner != t) {
1269                                 exceptions_throw_illegalmonitorstateexception();
1270                                 return;
1271                         }
1272                 }
1273                 else {
1274                         // It's a thin lock.
1275                         if (lockword->get_thin_lock_without_count() != t->thinlock) {
1276                                 exceptions_throw_illegalmonitorstateexception();
1277                                 return;
1278                         }
1279
1280                         // No thread can wait on a thin lock, so there's nothing to do.
1281                         return;
1282                 }
1283         }
1284
1285         // { The thread t owns the fat lock record lr on the object o }
1286         lock_record_notify(t, lr, one);
1287 }
1288
1289
1290
1291 /*============================================================================*/
1292 /* INQUIRY FUNCIONS                                                           */
1293 /*============================================================================*/
1294
1295
1296 /* lock_is_held_by_current_thread **********************************************
1297
1298    Return true if the current thread owns the monitor of the given object.
1299
1300    IN:
1301           o............the object
1302
1303    RETURN VALUE:
1304       true, if the current thread holds the lock of this object.
1305    
1306 *******************************************************************************/
1307
1308 bool lock_is_held_by_current_thread(java_handle_t *o)
1309 {
1310         // This function is inside a critical section.
1311         GCCriticalSection cs;
1312
1313         // Check if we own this monitor.
1314         // NOTE: We don't have to worry about stale values here, as any
1315         // stale value will fail this check.
1316         threadobject* t = thread_get_current();
1317         Lockword* lockword = lock_lockword_get(o);
1318
1319         if (lockword->is_fat_lock()) {
1320                 // It's a fat lock.
1321                 lock_record_t* lr = lockword->get_fat_lock();
1322                 return (lr->owner == t);
1323         }
1324         else {
1325                 // It's a thin lock.
1326                 return (lockword->get_thin_lock_without_count() == t->thinlock);
1327         }
1328 }
1329
1330
1331
1332 /*============================================================================*/
1333 /* WRAPPERS FOR OPERATIONS ON THE CURRENT THREAD                              */
1334 /*============================================================================*/
1335
1336
1337 /* lock_wait_for_object ********************************************************
1338
1339    Wait for the given object.
1340
1341    IN:
1342           o............the object
1343           millis.......milliseconds to wait
1344           nanos........nanoseconds to wait
1345    
1346 *******************************************************************************/
1347
1348 void lock_wait_for_object(java_handle_t *o, s8 millis, s4 nanos)
1349 {
1350         threadobject *thread;
1351
1352         thread = THREADOBJECT;
1353
1354         lock_monitor_wait(thread, o, millis, nanos);
1355 }
1356
1357
1358 /* lock_notify_object **********************************************************
1359
1360    Notify one thread waiting on the given object.
1361
1362    IN:
1363           o............the object
1364    
1365 *******************************************************************************/
1366
1367 void lock_notify_object(java_handle_t *o)
1368 {
1369         threadobject *thread;
1370
1371         thread = THREADOBJECT;
1372
1373         lock_monitor_notify(thread, o, true);
1374 }
1375
1376
1377 /* lock_notify_all_object ******************************************************
1378
1379    Notify all threads waiting on the given object.
1380
1381    IN:
1382           o............the object
1383    
1384 *******************************************************************************/
1385
1386 void lock_notify_all_object(java_handle_t *o)
1387 {
1388         threadobject *thread;
1389
1390         thread = THREADOBJECT;
1391
1392         lock_monitor_notify(thread, o, false);
1393 }
1394
1395
1396 /*
1397  * These are local overrides for various environment variables in Emacs.
1398  * Please do not remove this and leave it at the end of the file, where
1399  * Emacs will automagically detect them.
1400  * ---------------------------------------------------------------------
1401  * Local variables:
1402  * mode: c++
1403  * indent-tabs-mode: t
1404  * c-basic-offset: 4
1405  * tab-width: 4
1406  * End:
1407  * vim:noexpandtab:sw=4:ts=4:
1408  */