140905e2b6625ae6b6bf497ff41947e8bbf494e0
[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_finalization_proc ofinal = 0;
463                 GC_REGISTER_FINALIZER_UNREACHABLE(LLNI_DIRECT(o), lock_record_finalizer, 0, &ofinal, 0);
464
465                 /* There was a finalizer -- reinstall it. We do not want to disrupt the
466                    normal finalizer operation. We hold the monitor on this object, so
467                    this is thread-safe. */
468                 if (ofinal)
469                         GC_REGISTER_FINALIZER_NO_ORDER(LLNI_DIRECT(o), ofinal, 0, 0, 0);
470 #endif
471
472                 /* enter it in the hashtable */
473
474                 lr->hashlink             = lock_hashtable.ptr[slot];
475                 lock_hashtable.ptr[slot] = lr;
476                 lock_hashtable.entries++;
477
478                 /* check whether the hash should grow */
479
480                 if (lock_hashtable.entries * 3 > lock_hashtable.size * 4) {
481                         lock_hashtable_grow();
482                 }
483         }
484
485         // Unlock the hashtable.
486         lock_hashtable.mutex->unlock();
487
488         /* return the new lock record */
489
490         return lr;
491 }
492
493 /* lock_schedule_lockrecord_removal ********************************************
494
495    Gives the locking system a chance to schedule the removal of an unused lock
496    record. This function is called after an object's finalizer has run.
497
498    IN:
499           o....the object which has been finalized
500
501 *******************************************************************************/
502
503 #if defined(ENABLE_GC_BOEHM)
504 void lock_schedule_lockrecord_removal(java_handle_t *o)
505 {
506         Lockword* lockword = lock_lockword_get(o);
507         if (!lockword->is_fat_lock())
508                 /* there is no lock record */
509                 return;
510
511         /* register new finalizer to clean up the lock record */
512         GC_REGISTER_FINALIZER_UNREACHABLE(LLNI_DIRECT(o), lock_record_finalizer, 0, 0, 0);
513 }
514 #endif
515
516
517 /* lock_hashtable_remove *******************************************************
518
519    Remove the lock record for the given object from the hashtable
520    and free it afterwards.
521
522    IN:
523        t....the current thread
524        o....the object to look up
525
526 *******************************************************************************/
527
528 static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
529 {
530         lock_record_t *lr;
531         u4             slot;
532         lock_record_t *tmplr;
533
534         // Lock the hashtable.
535         lock_hashtable.mutex->lock();
536
537         /* get lock record */
538
539         Lockword* lockword = lock_lockword_get(o);
540
541         // Sanity check.
542         assert(lockword->is_fat_lock());
543
544         lr = lockword->get_fat_lock();
545
546         /* remove the lock-record from the hashtable */
547
548         slot  = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
549         tmplr = lock_hashtable.ptr[slot];
550
551         if (tmplr == lr) {
552                 /* special handling if it's the first in the chain */
553
554                 lock_hashtable.ptr[slot] = lr->hashlink;
555         }
556         else {
557                 for (; tmplr != NULL; tmplr = tmplr->hashlink) {
558                         if (tmplr->hashlink == lr) {
559                                 tmplr->hashlink = lr->hashlink;
560                                 break;
561                         }
562                 }
563
564                 assert(tmplr != NULL);
565         }
566
567         /* decrease entry count */
568
569         lock_hashtable.entries--;
570
571         // Unlock the hashtable.
572         lock_hashtable.mutex->unlock();
573
574         /* free the lock record */
575
576         lock_record_free(lr);
577 }
578
579
580 /* lock_record_finalizer *******************************************************
581
582    XXX Remove me for exact GC.
583
584 *******************************************************************************/
585
586 static void lock_record_finalizer(void *object, void *p)
587 {
588         java_handle_t *o;
589         classinfo     *c;
590
591         o = (java_handle_t *) object;
592
593 #if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
594         /* XXX this is only a dirty hack to make Boehm work with handles */
595
596         o = LLNI_WRAP((java_object_t *) o);
597 #endif
598
599         LLNI_class_get(o, c);
600
601 #if !defined(NDEBUG)
602         if (opt_DebugFinalizer) {
603                 log_start();
604                 log_print("[finalizer lockrecord: o=%p p=%p class=", object, p);
605                 class_print(c);
606                 log_print("]");
607                 log_finish();
608         }
609 #endif
610
611         /* remove the lock-record entry from the hashtable and free it */
612
613         lock_hashtable_remove(THREADOBJECT, o);
614 }
615
616
617 /*============================================================================*/
618 /* LOCKING ALGORITHM                                                          */
619 /*============================================================================*/
620
621
622 /* lock_lockword_get ***********************************************************
623
624    Get the lockword for the given object.
625
626    IN:
627       o............the object
628
629 *******************************************************************************/
630
631 static inline Lockword* lock_lockword_get(java_handle_t* o)
632 {
633 #if defined(ENABLE_GC_CACAO)
634         // Sanity check.
635         assert(GCCriticalSection::inside() == true);
636 #endif
637
638         return &(LLNI_DIRECT(o)->lockword);
639 }
640
641
642 /* lock_record_enter ***********************************************************
643
644    Enter the lock represented by the given lock record.
645
646    IN:
647       t.................the current thread
648           lr................the lock record
649
650 *******************************************************************************/
651
652 static inline void lock_record_enter(threadobject *t, lock_record_t *lr)
653 {
654         lr->mutex->lock();
655         lr->owner = t;
656 }
657
658
659 /* lock_record_exit ************************************************************
660
661    Release the lock represented by the given lock record.
662
663    IN:
664       t.................the current thread
665           lr................the lock record
666
667    PRE-CONDITION:
668       The current thread must own the lock represented by this lock record.
669           This is NOT checked by this function!
670
671 *******************************************************************************/
672
673 static inline void lock_record_exit(threadobject *t, lock_record_t *lr)
674 {
675         lr->owner = NULL;
676         lr->mutex->unlock();
677 }
678
679
680 /* lock_inflate ****************************************************************
681
682    Inflate the lock of the given object. This may only be called by the
683    owner of the monitor of the object.
684
685    IN:
686           o............the object of which to inflate the lock
687           lr...........the lock record to install. The current thread must
688                        own the lock of this lock record!
689
690    PRE-CONDITION:
691       The current thread must be the owner of this object's monitor AND
692           of the lock record's lock!
693
694 *******************************************************************************/
695
696 static void lock_inflate(java_handle_t *o, lock_record_t *lr)
697 {
698         Lockword* lockword = lock_lockword_get(o);
699         lockword->inflate(lr);
700 }
701
702
703 /* sable_flc_waiting ***********************************************************
704
705    Enqueue the current thread on another thread's FLC list. The function
706    blocks until the lock has been inflated by the owning thread.
707
708    The algorithm used to be an almost literal copy from SableVM. The
709    superfluous list traversal in the waiting loop has been removed since,
710    though.
711
712    IN:
713           lockword.....the object's lockword as seen at the first locking attempt
714           t............the current thread
715           o............the object of which to enter the monitor
716
717 *******************************************************************************/
718
719 static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t *o)
720 {
721         int32_t index;
722         threadobject *t_other;
723         int old_flc;
724
725         index = lockword->get_thin_lock_thread_index();
726         t_other = ThreadList::get_thread_by_index(index);
727
728         // The lockword could have changed during our way here.  If the
729         // thread index is zero, the lock got unlocked and we simply
730         // return.
731         if (t_other == NULL)
732 /*              failure, TODO: add statistics */
733                 return;
734
735         t_other->flc_lock->lock();
736         old_flc = t_other->flc_bit;
737         t_other->flc_bit = true;
738
739         DEBUGLOCKS(("thread %d set flc bit for lock-holding thread %d", t->index, t_other->index));
740
741         // Set FLC bit first, then read the lockword again.
742         Atomic::memory_barrier();
743
744         lockword = lock_lockword_get(o);
745
746         /* Lockword is still the way it was seen before */
747         if (lockword->is_thin_lock() && (lockword->get_thin_lock_thread_index() == index))
748         {
749                 threadobject *f;
750                 /* Add tuple (t, o) to the other thread's FLC list */
751                 t->flc_object = o;
752                 t->flc_next = t_other->flc_list;
753                 t_other->flc_list = t;
754                 if (t->flc_next == 0)
755                         t_other->flc_tail = t;
756                 f = t_other->flc_tail;
757
758                 // The other thread will clear flc_object.
759                 while (t->flc_object)
760                 {
761                         // We are not cleared yet -- the other thread cannot have seen
762                         // the FLC bit yet.
763                         assert(t_other->flc_bit);
764
765                         // Wait until another thread sees the flc bit and notifies
766                         // us of unlocking.
767                         t->flc_cond->wait(t_other->flc_lock);
768                 }
769
770                 t->flc_next = NULL;
771         }
772         else
773                 t_other->flc_bit = old_flc;
774
775         t_other->flc_lock->unlock();
776 }
777
778 /* notify_flc_waiters **********************************************************
779
780    Traverse the thread's FLC list and inflate all corresponding locks. Notify
781    the associated threads as well.
782
783    IN:
784           t............the current thread
785           o............the object currently being unlocked
786
787 *******************************************************************************/
788
789 static void notify_flc_waiters(threadobject *t, java_handle_t *o)
790 {
791         threadobject *current;
792
793         t->flc_lock->lock();
794
795         current = t->flc_list;
796         while (current)
797         {
798                 if (current->flc_object != o)
799                 {
800                         /* The object has to be inflated so the other threads can properly
801                            block on it. */
802
803                         // Only if not already inflated.
804                         Lockword* lockword = lock_lockword_get(current->flc_object);
805                         if (lockword->is_thin_lock()) {
806                                 lock_record_t *lr = lock_hashtable_get(current->flc_object);
807                                 lock_record_enter(t, lr);
808
809                                 DEBUGLOCKS(("thread %d inflating lock of %p to lr %p",
810                                                         t->index, (void*) current->flc_object, (void*) lr));
811
812                                 lock_inflate(current->flc_object, lr);
813                         }
814                 }
815
816                 // Wake the waiting threads.
817                 current->flc_cond->broadcast();
818                 current->flc_object = NULL;
819
820                 current = current->flc_next;
821         }
822
823         t->flc_list = NULL;
824         t->flc_bit = false;
825
826         t->flc_lock->unlock();
827 }
828
829 /* lock_monitor_enter **********************************************************
830
831    Acquire the monitor of the given object. If the current thread already
832    owns the monitor, the lock counter is simply increased.
833
834    This function blocks until it can acquire the monitor.
835
836    IN:
837       t............the current thread
838           o............the object of which to enter the monitor
839
840    RETURN VALUE:
841       true.........the lock has been successfully acquired
842           false........an exception has been thrown
843
844 *******************************************************************************/
845
846 bool lock_monitor_enter(java_handle_t *o)
847 {
848         // This function is inside a critical section.
849         GCCriticalSection cs;
850
851         if (o == NULL) {
852                 exceptions_throw_nullpointerexception();
853                 return false;
854         }
855
856         threadobject* t = thread_get_current();
857
858         uintptr_t thinlock = t->thinlock;
859
860 retry:
861         // Most common case: try to thin-lock an unlocked object.
862         Lockword* lockword = lock_lockword_get(o);
863         bool result = lockword->lock(thinlock);
864
865         if (result == true) {
866                 // Success, we locked it.
867                 // NOTE: The Java Memory Model requires a memory barrier here.
868 #if defined(CAS_PROVIDES_FULL_BARRIER) && CAS_PROVIDES_FULL_BARRIER
869                 // On some architectures, the CAS (hidden in the
870                 // lockword->lock call above), already provides this barrier,
871                 // so we only need to inform the compiler.
872                 Atomic::instruction_barrier();
873 #else
874                 Atomic::memory_barrier();
875 #endif
876                 return true;
877         }
878
879         // Next common case: recursive lock with small recursion count.
880         // NOTE: We don't have to worry about stale values here, as any
881         // stale value will indicate another thread holding the lock (or
882         // an inflated lock).
883         if (lockword->get_thin_lock_without_count() == thinlock) {
884                 // We own this monitor.  Check the current recursion count.
885                 if (lockword->is_max_thin_lock_count() == false) {
886                         // The recursion count is low enough.
887                         lockword->increase_thin_lock_count();
888
889                         // Success, we locked it.
890                         return true;
891                 }
892                 else {
893                         // Recursion count overflow.
894                         lock_record_t* lr = lock_hashtable_get(o);
895                         lock_record_enter(t, lr);
896                         lock_inflate(o, lr);
897                         lr->count++;
898
899                         notify_flc_waiters(t, o);
900
901                         return true;
902                 }
903         }
904
905         // The lock is either contented or fat.
906         if (lockword->is_fat_lock()) {
907                 lock_record_t* lr = lockword->get_fat_lock();
908
909                 // Check for recursive entering.
910                 if (lr->owner == t) {
911                         lr->count++;
912                         return true;
913                 }
914
915                 // Acquire the mutex of the lock record.
916                 lock_record_enter(t, lr);
917
918                 // Sanity check.
919                 assert(lr->count == 0);
920                 return true;
921         }
922
923         /****** inflation path ******/
924
925 #if defined(ENABLE_JVMTI)
926         /* Monitor Contended Enter */
927         jvmti_MonitorContendedEntering(false, o);
928 #endif
929
930         sable_flc_waiting(lockword, t, o);
931
932 #if defined(ENABLE_JVMTI)
933         /* Monitor Contended Entered */
934         jvmti_MonitorContendedEntering(true, o);
935 #endif
936         goto retry;
937 }
938
939
940 /* lock_monitor_exit ***********************************************************
941
942    Decrement the counter of a (currently owned) monitor. If the counter
943    reaches zero, release the monitor.
944
945    If the current thread is not the owner of the monitor, an 
946    IllegalMonitorState exception is thrown.
947
948    IN:
949       t............the current thread
950           o............the object of which to exit the monitor
951
952    RETURN VALUE:
953       true.........everything ok,
954           false........an exception has been thrown
955
956 *******************************************************************************/
957
958 bool lock_monitor_exit(java_handle_t* o)
959 {
960         // This function is inside a critical section.
961         GCCriticalSection cs;
962
963         if (o == NULL) {
964                 exceptions_throw_nullpointerexception();
965                 return false;
966         }
967
968         threadobject* t = thread_get_current();
969
970         uintptr_t thinlock = t->thinlock;
971
972         // We don't have to worry about stale values here, as any stale
973         // value will indicate that we don't own the lock.
974         Lockword* lockword = lock_lockword_get(o);
975
976         // Most common case: we release a thin lock that we hold once.
977         if (lockword->get_thin_lock() == thinlock) {
978                 // Memory barrier for Java Memory Model.
979                 Atomic::write_memory_barrier();
980                 lockword->unlock();
981                 // Memory barrier for FLC bit testing.
982                 Atomic::memory_barrier();
983
984                 /* check if there has been a flat lock contention on this object */
985
986                 if (t->flc_bit) {
987                         DEBUGLOCKS(("thread %d saw flc bit", t->index));
988
989                         /* there has been a contention on this thin lock */
990                         notify_flc_waiters(t, o);
991                 }
992
993                 return true;
994         }
995
996         // Next common case: we release a recursive lock, count > 0.
997         if (lockword->get_thin_lock_without_count() == thinlock) {
998                 lockword->decrease_thin_lock_count();
999                 return true;
1000         }
1001
1002         // Either the lock is fat, or we don't hold it at all.
1003         if (lockword->is_fat_lock()) {
1004                 lock_record_t* lr = lockword->get_fat_lock();
1005
1006                 // Check if we own this monitor.
1007                 // NOTE: We don't have to worry about stale values here, as
1008                 // any stale value will be != t and thus fail this check.
1009                 if (lr->owner != t) {
1010                         exceptions_throw_illegalmonitorstateexception();
1011                         return false;
1012                 }
1013
1014                 /* { the current thread `t` owns the lock record `lr` on object `o` } */
1015
1016                 if (lr->count != 0) {
1017                         // We had locked this one recursively.  Just decrement, it
1018                         // will still be locked.
1019                         lr->count--;
1020                         return true;
1021                 }
1022
1023                 // Unlock this lock record.
1024                 lock_record_exit(t, lr);
1025                 return true;
1026         }
1027
1028         // Legal thin lock cases have been handled above, so this is an
1029         // error.
1030         exceptions_throw_illegalmonitorstateexception();
1031
1032         return false;
1033 }
1034
1035
1036 /* lock_record_add_waiter ******************************************************
1037
1038    Add a thread to the list of waiting threads of a lock record.
1039
1040    IN:
1041       lr...........the lock record
1042       thread.......the thread to add
1043
1044 *******************************************************************************/
1045
1046 static void lock_record_add_waiter(lock_record_t *lr, threadobject* t)
1047 {
1048         // Add the thread as last entry to waiters list.
1049         lr->waiters->push_back(t);
1050
1051 #if defined(ENABLE_STATISTICS)
1052         if (opt_stat)
1053                 size_lock_waiter += sizeof(threadobject*);
1054 #endif
1055 }
1056
1057
1058 /* lock_record_remove_waiter ***************************************************
1059
1060    Remove a thread from the list of waiting threads of a lock record.
1061
1062    IN:
1063       lr...........the lock record
1064       t............the current thread
1065
1066    PRE-CONDITION:
1067       The current thread must be the owner of the lock record.
1068    
1069 *******************************************************************************/
1070
1071 static void lock_record_remove_waiter(lock_record_t *lr, threadobject* t)
1072 {
1073         // Remove the thread from the waiters.
1074         lr->waiters->remove(t);
1075
1076 #if defined(ENABLE_STATISTICS)
1077         if (opt_stat)
1078                 size_lock_waiter -= sizeof(threadobject*);
1079 #endif
1080 }
1081
1082
1083 /* lock_record_wait ************************************************************
1084
1085    Wait on a lock record for a given (maximum) amount of time.
1086
1087    IN:
1088       t............the current thread
1089           lr...........the lock record
1090           millis.......milliseconds of timeout
1091           nanos........nanoseconds of timeout
1092
1093    RETURN VALUE:
1094       true.........we have been interrupted,
1095       false........everything ok
1096
1097    PRE-CONDITION:
1098       The current thread must be the owner of the lock record.
1099           This is NOT checked by this function!
1100    
1101 *******************************************************************************/
1102
1103 static bool lock_record_wait(threadobject *thread, lock_record_t *lr, s8 millis, s4 nanos)
1104 {
1105         s4   lockcount;
1106         bool wasinterrupted = false;
1107
1108         DEBUGLOCKS(("[lock_record_wait  : lr=%p, t=%p, millis=%lld, nanos=%d]",
1109                                 lr, thread, millis, nanos));
1110
1111         /* { the thread t owns the fat lock record lr on the object o } */
1112
1113         /* register us as waiter for this object */
1114
1115         lock_record_add_waiter(lr, thread);
1116
1117         /* remember the old lock count */
1118
1119         lockcount = lr->count;
1120
1121         /* unlock this record */
1122
1123         lr->count = 0;
1124         lock_record_exit(thread, lr);
1125
1126         /* wait until notified/interrupted/timed out */
1127
1128         threads_wait_with_timeout_relative(thread, millis, nanos);
1129
1130         /* re-enter the monitor */
1131
1132         lock_record_enter(thread, lr);
1133
1134         /* remove us from the list of waiting threads */
1135
1136         lock_record_remove_waiter(lr, thread);
1137
1138         /* restore the old lock count */
1139
1140         lr->count = lockcount;
1141
1142         /* We can only be signaled OR interrupted, not both. If both flags
1143            are set, reset only signaled and leave the thread in
1144            interrupted state. Otherwise, clear both. */
1145
1146         if (!thread->signaled) {
1147                 wasinterrupted = thread->interrupted;
1148                 thread->interrupted = false;
1149         }
1150
1151         thread->signaled = false;
1152
1153         /* return if we have been interrupted */
1154
1155         return wasinterrupted;
1156 }
1157
1158
1159 /* lock_monitor_wait ***********************************************************
1160
1161    Wait on an object for a given (maximum) amount of time.
1162
1163    IN:
1164       t............the current thread
1165           o............the object
1166           millis.......milliseconds of timeout
1167           nanos........nanoseconds of timeout
1168
1169    PRE-CONDITION:
1170       The current thread must be the owner of the object's monitor.
1171    
1172 *******************************************************************************/
1173
1174 static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 nanos)
1175 {
1176         lock_record_t *lr;
1177
1178         Lockword* lockword = lock_lockword_get(o);
1179
1180         // Check if we own this monitor.
1181         // NOTE: We don't have to worry about stale values here, as any
1182         // stale value will fail this check.
1183         if (lockword->is_fat_lock()) {
1184                 lr = lockword->get_fat_lock();
1185
1186                 if (lr->owner != t) {
1187                         exceptions_throw_illegalmonitorstateexception();
1188                         return;
1189                 }
1190         }
1191         else {
1192                 // It's a thin lock.
1193                 if (lockword->get_thin_lock_without_count() != t->thinlock) {
1194                         exceptions_throw_illegalmonitorstateexception();
1195                         return;
1196                 }
1197
1198                 // Get the lock-record.
1199                 lr = lock_hashtable_get(o);
1200                 lock_record_enter(t, lr);
1201
1202                 // Inflate this lock.
1203                 lockword->inflate(lr);
1204
1205                 notify_flc_waiters(t, o);
1206         }
1207
1208         /* { the thread t owns the fat lock record lr on the object o } */
1209
1210         if (lock_record_wait(t, lr, millis, nanos))
1211                 exceptions_throw_interruptedexception();
1212 }
1213
1214
1215 /* lock_record_notify **********************************************************
1216
1217    Notify one thread or all threads waiting on the given lock record.
1218
1219    IN:
1220       t............the current thread
1221           lr...........the lock record
1222           one..........if true, only notify one thread
1223
1224    PRE-CONDITION:
1225       The current thread must be the owner of the lock record.
1226           This is NOT checked by this function!
1227    
1228 *******************************************************************************/
1229
1230 static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
1231 {
1232 #if defined(ENABLE_GC_CACAO)
1233         // Sanity check.
1234         assert(GCCriticalSection::inside() == false);
1235 #endif
1236
1237         // { The thread t owns the fat lock record lr on the object o }
1238
1239         for (List<threadobject*>::iterator it = lr->waiters->begin(); it != lr->waiters->end(); it++) {
1240                 threadobject* waiter = *it;
1241
1242                 // We must skip threads which have already been notified. They
1243                 // will remove themselves from the list.
1244                 if (waiter->signaled)
1245                         continue;
1246
1247                 // Enter the wait-mutex.
1248                 waiter->waitmutex->lock();
1249
1250                 DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, one=%d]", lr, t, waiter, one));
1251
1252                 // Signal the waiter.
1253                 waiter->waitcond->signal();
1254
1255                 // Mark the thread as signaled.
1256                 waiter->signaled = true;
1257
1258                 // Leave the wait-mutex.
1259                 waiter->waitmutex->unlock();
1260
1261                 // If we should only wake one thread, we are done.
1262                 if (one)
1263                         break;
1264         }
1265 }
1266
1267
1268 /* lock_monitor_notify *********************************************************
1269
1270    Notify one thread or all threads waiting on the given object.
1271
1272    IN:
1273       t............the current thread
1274           o............the object
1275           one..........if true, only notify one thread
1276
1277    PRE-CONDITION:
1278       The current thread must be the owner of the object's monitor.
1279    
1280 *******************************************************************************/
1281
1282 static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one)
1283 {
1284         lock_record_t* lr = NULL;
1285
1286         {
1287                 // This scope is inside a critical section.
1288                 GCCriticalSection cs;
1289
1290                 Lockword* lockword = lock_lockword_get(o);
1291
1292                 // Check if we own this monitor.
1293                 // NOTE: We don't have to worry about stale values here, as any
1294                 // stale value will fail this check.
1295
1296                 if (lockword->is_fat_lock()) {
1297                         lr = lockword->get_fat_lock();
1298
1299                         if (lr->owner != t) {
1300                                 exceptions_throw_illegalmonitorstateexception();
1301                                 return;
1302                         }
1303                 }
1304                 else {
1305                         // It's a thin lock.
1306                         if (lockword->get_thin_lock_without_count() != t->thinlock) {
1307                                 exceptions_throw_illegalmonitorstateexception();
1308                                 return;
1309                         }
1310
1311                         // No thread can wait on a thin lock, so there's nothing to do.
1312                         return;
1313                 }
1314         }
1315
1316         // { The thread t owns the fat lock record lr on the object o }
1317         lock_record_notify(t, lr, one);
1318 }
1319
1320
1321
1322 /*============================================================================*/
1323 /* INQUIRY FUNCIONS                                                           */
1324 /*============================================================================*/
1325
1326
1327 /* lock_is_held_by_current_thread **********************************************
1328
1329    Return true if the current thread owns the monitor of the given object.
1330
1331    IN:
1332           o............the object
1333
1334    RETURN VALUE:
1335       true, if the current thread holds the lock of this object.
1336    
1337 *******************************************************************************/
1338
1339 bool lock_is_held_by_current_thread(java_handle_t *o)
1340 {
1341         // This function is inside a critical section.
1342         GCCriticalSection cs;
1343
1344         // Check if we own this monitor.
1345         // NOTE: We don't have to worry about stale values here, as any
1346         // stale value will fail this check.
1347         threadobject* t = thread_get_current();
1348         Lockword* lockword = lock_lockword_get(o);
1349
1350         if (lockword->is_fat_lock()) {
1351                 // It's a fat lock.
1352                 lock_record_t* lr = lockword->get_fat_lock();
1353                 return (lr->owner == t);
1354         }
1355         else {
1356                 // It's a thin lock.
1357                 return (lockword->get_thin_lock_without_count() == t->thinlock);
1358         }
1359 }
1360
1361
1362
1363 /*============================================================================*/
1364 /* WRAPPERS FOR OPERATIONS ON THE CURRENT THREAD                              */
1365 /*============================================================================*/
1366
1367
1368 /* lock_wait_for_object ********************************************************
1369
1370    Wait for the given object.
1371
1372    IN:
1373           o............the object
1374           millis.......milliseconds to wait
1375           nanos........nanoseconds to wait
1376    
1377 *******************************************************************************/
1378
1379 void lock_wait_for_object(java_handle_t *o, s8 millis, s4 nanos)
1380 {
1381         threadobject *thread;
1382
1383         thread = THREADOBJECT;
1384
1385         lock_monitor_wait(thread, o, millis, nanos);
1386 }
1387
1388
1389 /* lock_notify_object **********************************************************
1390
1391    Notify one thread waiting on the given object.
1392
1393    IN:
1394           o............the object
1395    
1396 *******************************************************************************/
1397
1398 void lock_notify_object(java_handle_t *o)
1399 {
1400         threadobject *thread;
1401
1402         thread = THREADOBJECT;
1403
1404         lock_monitor_notify(thread, o, true);
1405 }
1406
1407
1408 /* lock_notify_all_object ******************************************************
1409
1410    Notify all threads waiting on the given object.
1411
1412    IN:
1413           o............the object
1414    
1415 *******************************************************************************/
1416
1417 void lock_notify_all_object(java_handle_t *o)
1418 {
1419         threadobject *thread;
1420
1421         thread = THREADOBJECT;
1422
1423         lock_monitor_notify(thread, o, false);
1424 }
1425
1426
1427 /*
1428  * These are local overrides for various environment variables in Emacs.
1429  * Please do not remove this and leave it at the end of the file, where
1430  * Emacs will automagically detect them.
1431  * ---------------------------------------------------------------------
1432  * Local variables:
1433  * mode: c++
1434  * indent-tabs-mode: t
1435  * c-basic-offset: 4
1436  * tab-width: 4
1437  * End:
1438  * vim:noexpandtab:sw=4:ts=4:
1439  */