/** * Initializes raw monitor. * * Raw monitors are a simple combination of mutex and conditional variable which is * not associated with any Java object. This function creates the raw monitor at the * address specified as mon_ptr. * User needs to allocate space equal to sizeof(jrawMonitorID) before doing this call. * * @param[in] mon_ptr address where monitor needs to be created and initialized. */ IDATA VMCALL jthread_raw_monitor_create(jrawMonitorID * mon_ptr) { assert(mon_ptr); hythread_monitor_t monitor; IDATA status = hythread_monitor_init(&monitor, 0); if (status != TM_ERROR_NONE) { return status; } // possibly should be moved to jvmti(environment?) init section if (!jvmti_monitor_table) { status = jthread_init_jvmti_monitor_table(); if (status != TM_ERROR_NONE) { return status; } } status = port_mutex_lock(&jvmti_monitor_table_lock); if (status != TM_ERROR_NONE) { return status; } *mon_ptr = (jrawMonitorID)array_add(jvmti_monitor_table, monitor); if (!(*mon_ptr)) { port_mutex_unlock(&jvmti_monitor_table_lock); return TM_ERROR_OUT_OF_MEMORY; } status = port_mutex_unlock(&jvmti_monitor_table_lock); return status; } // jthread_raw_monitor_create
/* * Inflates the compressed lockword into fat fat_monitor */ hythread_monitor_t VMCALL hythread_inflate_lock(hythread_thin_monitor_t *lockword_ptr) { hythread_monitor_t fat_monitor; IDATA status; IDATA fat_monitor_id; U_32 lockword; int i; // we don't need to write lock on lock_table during all this function because // the only invariant we need is 'fat lock is not in the fat lock table before we put it' // however this invariant is true because we hold monitor->mutex during this function // so it cannot be called twice for the signle monitor concurrently lockword = *lockword_ptr; if (IS_FAT_LOCK (lockword)) { return locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); } #ifdef LOCK_RESERVATION // unreserve lock first if (IS_RESERVED(lockword)) { unreserve_self_lock(lockword_ptr); lockword = *lockword_ptr; } assert(!IS_RESERVED(lockword)); #endif assert(hythread_owns_thin_lock(tm_self_tls, lockword)); assert(!hythread_is_suspend_enabled()); CTRACE(("inflation begin for %x thread: %d", lockword, tm_self_tls->thread_id)); status = hythread_monitor_init(&fat_monitor, 0); // allocate fat fat_monitor //assert(status == TM_ERROR_NONE); if (status != TM_ERROR_NONE) { return NULL; } status = hythread_monitor_enter(fat_monitor); if (status != TM_ERROR_NONE) { return NULL; } for (i = RECURSION(lockword); i > 0; i--) { CTRACE(("inflate recursion monitor")); status = hythread_monitor_enter(fat_monitor); // transfer recursion count to fat fat_monitor assert(status == TM_ERROR_NONE); } fat_monitor_id = locktable_put_fat_monitor(fat_monitor); // put fat_monitor into lock table set_fat_lock_id(lockword_ptr, fat_monitor_id); CTRACE(("hythread_inflate_lock %d thread: %d\n", FAT_LOCK_ID(*lockword_ptr), tm_self_tls->thread_id)); //assert(FAT_LOCK_ID(*lockword_ptr) != 2); CTRACE(("FAT ID : 0x%x", *lockword_ptr)); #ifdef LOCK_RESERVATION assert(!IS_RESERVED(*lockword_ptr)); #endif return fat_monitor; }
/** * Initializes a new thread structure. */ IDATA VMCALL hythread_struct_init(hythread_t new_thread) { char jstatus; IDATA status; assert(new_thread); jstatus = new_thread->java_status; if (!new_thread->os_handle) { // new thread, create thread primitives memset(new_thread, 0, sizeof(HyThread)); status = hysem_create(&new_thread->resume_event, 0, 1); assert(status == TM_ERROR_NONE); status = port_mutex_create(&new_thread->mutex, APR_THREAD_MUTEX_NESTED); assert(status == TM_ERROR_NONE); status = hythread_monitor_init(&new_thread->monitor, 0); assert(status == TM_ERROR_NONE); } else { // old thread, reset structure int result; hysem_t resume; osmutex_t mutex; hythread_monitor_t monitor; // release thread OS handle result = port_thread_free_handle(new_thread->os_handle); assert(0 == result); resume = new_thread->resume_event; mutex = new_thread->mutex; monitor = new_thread->monitor; // zero new thread memset(new_thread, 0, sizeof(HyThread)); new_thread->resume_event = resume; new_thread->mutex = mutex; new_thread->monitor = monitor; } assert(new_thread->os_handle == 0); new_thread->java_status = jstatus; new_thread->priority = HYTHREAD_PRIORITY_NORMAL; #ifdef ORDER new_thread->alloc_count = 0; new_thread->thread_create_count = 0; new_thread->p_tid = 0; new_thread->p_count = 0; // new_thread->isInVMRegistry = 0; #endif port_mutex_lock(&new_thread->mutex); new_thread->state = TM_THREAD_STATE_NEW; port_mutex_unlock(&new_thread->mutex); status = hysem_set(new_thread->resume_event, 0); assert(status == TM_ERROR_NONE); return TM_ERROR_NONE; }