Ejemplo n.º 1
0
/* A method's quick prepare info list holds prepare information for all
   blocks within the method that end with a quickened instruction.  If
   the quickened instruction being executed is in the list we must have
   reached the end of a block and we need to inline it */
void checkInliningQuickenedInstruction(Instruction *pc, MethodBlock *mb) {

    /* As there could be multiple threads executing this method,
       the list must be protected with a lock.  However, the 
       fast case of an empty list doesn't need locking. */
    if(mb->quick_prepare_info) {
        QuickPrepareInfo *info, *last = NULL;

        Thread *self = threadSelf();
        rewriteLock(self);

        /* Search list */
        info = mb->quick_prepare_info;
        for(; info && info->quickened != pc; last = info, info = info->next);

        /* If prepare info found, remove it from the list */
        if(info) {
            if(last)
                last->next = info->next;
            else
                mb->quick_prepare_info = info->next;
        }

        rewriteUnlock(self);

        /* If prepare info found, inline block (no need to
           hold lock) */
        if(info) {
            inlineBlock(mb, &info->block);
            sysFree(info);
        }
    }
}
Ejemplo n.º 2
0
void inlineBlockWrappedOpcode(MethodBlock *mb, Instruction *pc) {
    PrepareInfo *prepare_info = pc->operand.pntr;
    OpcodeInfo *info;
    int i;

    Thread *self = threadSelf();
    rewriteLock(self);

    for(i = 0; i < HANDLERS; i++)
        if(pc->handler == handler_entry_points[i][OPC_INLINE_REWRITER])
            break;

    if(i == HANDLERS) {
        rewriteUnlock(self);
        return;
    }

    pc->handler = handler_entry_points[0][GOTO_START];
    rewriteUnlock(self);

    /* Unwrap the original handler's operand */
    pc->operand = prepare_info->operand;
    MBARRIER();

    /* Unwrap the original handler */
    info = &prepare_info->block.opcodes[prepare_info->block.length-1];
    pc->handler = handler_entry_points[info->cache_depth][info->opcode];

    inlineBlock(mb, &prepare_info->block);
    sysFree(prepare_info);
}
Ejemplo n.º 3
0
void objectUnlock(Object *obj) {
    Thread *self = threadSelf();
    uintptr_t lockword = LOCKWORD_READ(&obj->lock);
    uintptr_t thin_locked = self->id<<TID_SHIFT;

    TRACE("Thread %p unlock on obj %p...\n", self, obj);

    if(lockword == thin_locked) {
        /* This barrier is not needed for the thin-locking implementation;
           it's a requirement of the Java memory model. */
        JMM_UNLOCK_MBARRIER();
        LOCKWORD_WRITE(&obj->lock, 0);

        /* Required by thin-locking mechanism. */
        MBARRIER();

retry:
        if(testFlcBit(obj)) {
            Monitor *mon = findMonitor(obj);

            if(!monitorTryLock(mon, self)) {
                threadYield(self);
                goto retry;
            }

            if(testFlcBit(obj) && (mon->obj == obj))
                monitorNotify(mon, self);

            monitorUnlock(mon, self);
        }
    } else {
        if((lockword & (TID_MASK|SHAPE_BIT)) == thin_locked)
            LOCKWORD_WRITE(&obj->lock, lockword - (1<<COUNT_SHIFT));
        else
            if((lockword & SHAPE_BIT) != 0) {
                Monitor *mon = (Monitor*) (lockword & ~SHAPE_BIT);

                if((mon->count == 0) && (LOCKWORD_READ(&mon->entering) == 0) &&
                                (mon->in_wait == 0)) {
                    TRACE("Thread %p is deflating obj %p...\n", self, obj);

                    /* This barrier is not needed for the thin-locking
                       implementation; it's a requirement of the Java
                       memory model. */
                    JMM_UNLOCK_MBARRIER();

                    LOCKWORD_WRITE(&obj->lock, 0);
                    LOCKWORD_COMPARE_AND_SWAP(&mon->entering, 0, UN_USED);
                }

                monitorUnlock(mon, self);
            }
    }
}
Ejemplo n.º 4
0
void resetPeakThreadsCount() {
    Thread *self = threadSelf();

    /* Grab the thread lock to protect against
       concurrent update by threads starting/dying */
    disableSuspend(self);
    pthread_mutex_lock(&lock);
    peak_threads_count = threads_count;
    pthread_mutex_unlock(&lock);
    enableSuspend(self);
}
Ejemplo n.º 5
0
void createJavaThread(Object *jThread, long long stack_size) {
    //ExecEnv *ee;
    Thread *thread;
    Thread *self = threadSelf();
    Object *vmthread = allocObject(vmthread_class);

    if(vmthread == NULL)
        return;

    disableSuspend(self);

    pthread_mutex_lock(&lock);
    if(INST_DATA(jThread)[vmthread_offset]) {
        pthread_mutex_unlock(&lock);
        enableSuspend(self);
        signalException(java_lang_IllegalThreadStateException, "thread already started");
        return;
    }

    //ee = (ExecEnv*)sysMalloc(sizeof(ExecEnv));
    thread = new Thread;
    //memset(ee, 0, sizeof(ExecEnv));

//     thread->ee = ee;
//     ee->thread = jThread;
    thread->thread = jThread;
    //    ee->stack_size = stack_size;


    INST_DATA(vmthread)[vmData_offset] = (uintptr_t)thread;
    INST_DATA(vmthread)[thread_offset] = (uintptr_t)jThread;
    INST_DATA(jThread)[vmthread_offset] = (uintptr_t)vmthread;

    pthread_mutex_unlock(&lock);

    if(pthread_create(&thread->tid, &attributes, threadStart, thread)) {
        INST_DATA(jThread)[vmthread_offset] = 0;
        //sysFree(ee);
        enableSuspend(self);
        signalException(java_lang_OutOfMemoryError, "can't create thread");
        return;
    }

    pthread_mutex_lock(&lock);

    /* Wait for thread to start */
    while(thread->state == 0)
        pthread_cond_wait(&cv, &lock);

    pthread_mutex_unlock(&lock);
    enableSuspend(self);
}
bool Thread::checkHardRealtime()
{
#ifdef _SYSTEM_LXRT_
  if (threadSelf() && os::isThisHRT() && !isHardRealtime() && m_priority < 0)
  {
    return setHardRealtime(true);
  }
  else
#endif
  {
    return false;
  }
}
Ejemplo n.º 7
0
void mainThreadWaitToExitVM() {
    Thread *self = threadSelf();
    TRACE("Waiting for %d non-daemon threads to exit\n", non_daemon_thrds);

    disableSuspend(self);
    pthread_mutex_lock(&exit_lock);

    self->state = WAITING;
    while(non_daemon_thrds)
        pthread_cond_wait(&exit_cv, &exit_lock);

    pthread_mutex_unlock(&exit_lock);
    enableSuspend(self);
}
Ejemplo n.º 8
0
void objectWait0(Object *obj, long long ms, int ns, int interruptible) {
    uintptr_t lockword = LOCKWORD_READ(&obj->lock);
    Thread *self = threadSelf();
    Monitor *mon;

    TRACE("Thread %p Wait on obj %p...\n", self, obj);

    if((lockword & SHAPE_BIT) == 0) {
        int tid = (lockword&TID_MASK)>>TID_SHIFT;
        if(tid == self->id) {
            mon = findMonitor(obj);
            monitorLock(mon, self);
            inflate(obj, mon, self);
            mon->count = (lockword&COUNT_MASK)>>COUNT_SHIFT;
        } else
Ejemplo n.º 9
0
void threadInterrupt(Thread *thread) {
    Thread *self = threadSelf();
    Monitor *mon;

    /* MonitorWait sets wait_mon _before_ checking interrupted status.
       Therefore, if wait_mon is null, interrupted status will be noticed.
       This guards against a race-condition leading to an interrupt being
       missed.  The memory barrier ensures correct ordering on SMP systems. */
    thread->interrupted = TRUE;
    MBARRIER();

    if((mon = thread->wait_mon) != NULL && thread->wait_next != NULL) {
        int locked;
        thread->interrupting = TRUE;

        /* The thread is waiting on a monitor, but it may not have
           entered the wait (in which case the signal will be lost).
           Loop until we can get ownership (i.e. the thread has released
           it on waiting) */
        while(!(locked = !pthread_mutex_trylock(&mon->lock)) &&
                    mon->owner == NULL)
            sched_yield();

        pthread_cond_signal(&thread->wait_cv);

        if(locked)
            pthread_mutex_unlock(&mon->lock);
    }

    /* Thread may still be parked */
    threadUnpark(thread);

    /* Handle the case where the thread is blocked in a system call.
       This will knock it out with an EINTR.  The suspend signal
       handler will just return (as in the user doing a kill), and do
       nothing otherwise. */

    /* Note, under Linuxthreads pthread_kill obtains a lock on the thread
       being signalled.  If another thread is suspending all threads,
       and the interrupting thread is earlier in the thread list than the
       thread being interrupted, it can be suspended holding the lock.
       When the suspending thread tries to signal the interrupted thread
       it will deadlock.  To prevent this, disable suspension. */

    fastDisableSuspend(self);
    pthread_kill(thread->tid, SIGUSR1);
    fastEnableSuspend(self);
}
Ejemplo n.º 10
0
void objectLock(Object *obj) {
    Thread *self = threadSelf();
    uintptr_t thin_locked = self->id<<TID_SHIFT;
    uintptr_t entering, lockword;
    Monitor *mon;

    TRACE("Thread %p lock on obj %p...\n", self, obj);

    if(LOCKWORD_COMPARE_AND_SWAP(&obj->lock, 0, thin_locked)) {
        /* This barrier is not needed for the thin-locking implementation;
           it's a requirement of the Java memory model. */
        JMM_LOCK_MBARRIER();
        return;
    }

    lockword = LOCKWORD_READ(&obj->lock);
    if((lockword & (TID_MASK|SHAPE_BIT)) == thin_locked) {
        int count = lockword & COUNT_MASK;

        if(count < (((1<<COUNT_SIZE)-1)<<COUNT_SHIFT))
            LOCKWORD_WRITE(&obj->lock, lockword + (1<<COUNT_SHIFT));
        else {
            mon = findMonitor(obj);
            monitorLock(mon, self);
            inflate(obj, mon, self);
            mon->count = 1<<COUNT_SIZE;
        }
        return;
    }

try_again:
    mon = findMonitor(obj);

try_again2:
    if((entering = LOCKWORD_READ(&mon->entering)) == UN_USED)
        goto try_again;

    if(!(LOCKWORD_COMPARE_AND_SWAP(&mon->entering, entering, entering+1)))
        goto try_again2;

    if(mon->obj != obj) {
        while(entering = LOCKWORD_READ(&mon->entering),
                        !(LOCKWORD_COMPARE_AND_SWAP(&mon->entering,
                                                    entering, entering-1)));
        goto try_again;
    }

    monitorLock(mon, self);

    while(entering = LOCKWORD_READ(&mon->entering),
                    !(LOCKWORD_COMPARE_AND_SWAP(&mon->entering,
                                                entering, entering-1)));

    while((LOCKWORD_READ(&obj->lock) & SHAPE_BIT) == 0) {
        setFlcBit(obj);

        if(LOCKWORD_COMPARE_AND_SWAP(&obj->lock, 0, thin_locked))
            inflate(obj, mon, self);
        else
            monitorWait0(mon, self, 0, 0, TRUE, FALSE);
    }
}
Ejemplo n.º 11
0
//The following function is converted from the macro with the same name,since it may lead compiling error under
//Microsoft Visual Studio.
static void _findHashEntry(HashTable* table,Object* ptr,Monitor* ptr2,int add_if_absent,int scavenge,int locked)
{                                                                                  
    int hash;                                                                      
    int i;                                                                         
	Thread *self;                                                                  
                                                                                   
	hash = HASH(ptr);                                                              
    if(locked) {                                                                   
        self = threadSelf();                                                       
        lockHashTable0(table, self);                                              
    }                                                                              
                                                                                   
    i = hash & (table->hash_size - 1);                                             
                                                                                   
    for(;;) {                                                                      
        ptr2 = table->hash_table[i].data;                                          
        if((ptr2 == NULL) || (COMPARE(ptr, ptr2, hash, table->hash_table[i].hash))) 
            break;                                                                 
                                                                                   
        i = (i+1) & (table->hash_size - 1);                                        
    }                                                                              
                                                                                   
    if(ptr2) {                                                                     
        ptr2 = FOUND(ptr, ptr2);                                                   
    } else                                                                         
        if(add_if_absent) {                                                        
            table->hash_table[i].hash = hash;                                      
            ptr2 = table->hash_table[i].data = PREPARE(ptr);                       
                                                                                   
            if(ptr2) {                                                             
                table->hash_count++;                                               
                if((table->hash_count * 4) > (table->hash_size * 3)) {             
                    int new_size;                                                  
                    if(scavenge) {                                                 
                        HashEntry *entry = table->hash_table;                      
                        int cnt = table->hash_count;                               
                        for(; cnt; entry++) {                                      
                            void *data = entry->data;                              
                            if(data) {                                             
                                if(SCAVENGE(data)) {                               
                                    entry->data = NULL;                            
                                    table->hash_count--;                           
                                }                                                  
                                cnt--;                                             
                            }                                                      
                        }                                                          
                        if((table->hash_count * 3) > (table->hash_size * 2))       
                            new_size = table->hash_size*2;                         
                        else                                                       
                            new_size = table->hash_size;                           
                    } else                                                         
                        new_size = table->hash_size*2;                             
                                                                                   
                    resizeHash(table, new_size);                                  
                }                                                                 
            }                                                                     
        }                                                                         
                                                                                  
    if(locked)                                                                    
        unlockHashTable0(table, self);                                            
}
Ejemplo n.º 12
0
void dumpThreadsLoop(Thread *self) {
    //return;                     // do nothing for now
    //assert(false);

    char buffer[256];
    Thread *thread;
    sigset_t mask;
    int sig;

    sigemptyset(&mask);
    sigaddset(&mask, SIGQUIT);
    sigaddset(&mask, SIGINT);

    disableSuspend0(self, &self);
    for(;;) {
        sigwait(&mask, &sig);

        /* If it was an interrupt (e.g. Ctrl-C) terminate the VM */
        if(sig == SIGINT)
            exitVM(0);

        /* It must be a SIGQUIT.  Do a thread dump */

        suspendAllThreads(self);
        jam_printf("\n------ JamVM version %s Full Thread Dump -------\n", VERSION);

        for(thread = &main_thread; thread != NULL; thread = thread->next) {
            //uintptr_t *thr_data = INST_DATA(thread->ee->thread);
            uintptr_t *thr_data = INST_DATA(thread->thread);
            int priority = thr_data[priority_offset];
            int daemon = thr_data[daemon_offset];
            assert(false);
            //Frame *last = thread->ee->last_frame;
            Frame* last = threadSelf()->get_current_spmt_thread()->get_current_mode()->frame;

            /* Get thread name; we don't use String2Cstr(), as this mallocs memory
               and may deadlock with a thread suspended in malloc/realloc/free */
            String2Buff((Object*)thr_data[name_offset], buffer, sizeof(buffer));

            jam_printf("\n\"%s\"%s %p priority: %d tid: %p id: %d state: %s (%d)\n",
                  buffer, daemon ? " (daemon)" : "", thread, priority, thread->tid,
                  thread->id, getThreadStateString(thread), thread->state);

            while(last->prev != NULL) {
                for(; last->mb != NULL; last = last->prev) {
                    MethodBlock *mb = last->mb;
                    ClassBlock *cb = CLASS_CB(mb->classobj);

                    /* Convert slashes in class name to dots.  Similar to above,
                       we don't use slash2dots(), as this mallocs memory */
                    slash2dots2buff(cb->name, buffer, sizeof(buffer));
                    jam_printf("\tat %s.%s(", buffer, mb->name);

                    if(mb->is_native())
                        jam_printf("Native method");
                    else
                        if(cb->source_file_name == NULL)
                            jam_printf("Unknown source");
                        else {
                            int line = mapPC2LineNo(mb, last->last_pc);
                            jam_printf("%s", cb->source_file_name);
                            if(line != -1)
                                jam_printf(":%d", line);
                        }
                    jam_printf(")\n");
                }
                last = last->prev;
            }
        }
        resumeAllThreads(self);
    }
}
Ejemplo n.º 13
0
static void suspendHandler(int sig) {
    Thread *thread = threadSelf();
    suspendLoop(thread);
}
/*! Check whether the calling thread is the thread running by this
 *  object.
 *  \deprecated Obsolete coding style.
 */
bool Thread::ThreadSelf() const
{
  return threadSelf();
}