int calculate_donated_priority_up (struct thread* holder) { ASSERT (is_thread(holder)); int max_overall = -1, i; struct thread* t_max; for (i=0; i<lock_list_cnt; i++) { if (lock_list[i]->holder == holder) { struct list* waiter_list = &lock_list[i]->semaphore.waiters; if (list_size(waiter_list) == 0) continue; t_max = list_entry(list_max(waiter_list, priority_less, NULL), struct thread, elem); ASSERT(is_thread(t_max)); if (max_overall < t_max->effective_priority) max_overall = t_max->effective_priority; } } return max_overall; }
static int sol_thread_alive (ptid_t ptid) { if (is_thread (ptid)) /* non-kernel thread */ { td_err_e val; td_thrhandle_t th; int pid; pid = GET_THREAD (ptid); if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK) return 0; /* thread not found */ if ((val = p_td_thr_validate (&th)) != TD_OK) return 0; /* thread not valid */ return 1; /* known thread: return true */ } else /* kernel thread (LWP): let procfs test it */ { if (target_has_execution) return procfs_ops.to_thread_alive (ptid); else return orig_core_ops.to_thread_alive (ptid); } }
static LONGEST sol_thread_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, void *readbuf, const void *writebuf, ULONGEST offset, LONGEST len) { int retval; struct cleanup *old_chain; old_chain = save_inferior_ptid (); if (is_thread (inferior_ptid) || /* A thread */ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ inferior_ptid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ if (target_has_execution) retval = procfs_ops.to_xfer_partial (ops, object, annex, readbuf, writebuf, offset, len); else retval = orig_core_ops.to_xfer_partial (ops, object, annex, readbuf, writebuf, offset, len); do_cleanups (old_chain); return retval; }
static int sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite, struct mem_attrib *attrib, struct target_ops *target) { int retval; struct cleanup *old_chain; old_chain = save_inferior_ptid (); if (is_thread (inferior_ptid) || /* A thread */ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ inferior_ptid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ if (target_has_execution) retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target); else retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target); do_cleanups (old_chain); return retval; }
char * solaris_pid_to_str (ptid_t ptid) { static char buf[100]; /* in case init failed to resolve the libthread_db library */ if (!procfs_suppress_run) return procfs_pid_to_str (ptid); if (is_thread (ptid)) { ptid_t lwp; lwp = thread_to_lwp (ptid, -2); if (PIDGET (lwp) == -1) sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid)); else if (PIDGET (lwp) != -2) sprintf (buf, "Thread %ld (LWP %ld)", GET_THREAD (ptid), GET_LWP (lwp)); else sprintf (buf, "Thread %ld ", GET_THREAD (ptid)); } else if (GET_LWP (ptid) != 0) sprintf (buf, "LWP %ld ", GET_LWP (ptid)); else sprintf (buf, "process %d ", PIDGET (ptid)); return buf; }
/* Acquires LOCK, sleeping until it becomes available if necessary. The lock must not already be held by the current thread. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but interrupts will be turned back on if we need to sleep. */ void lock_acquire (struct lock *lock) { ASSERT (lock != NULL); ASSERT (!intr_context ()); ASSERT (!lock_held_by_current_thread (lock)); struct thread* acquirer = thread_current(); if (!thread_mlfqs) { // P2: add new lock to the lock_list. if (!is_thread(lock->holder)) { // add lock into locklist. bool found = 0; int i; for (i=0;i<lock_list_cnt; i++) if (lock_list[i] == lock) found = 1; if (found == 0) { ASSERT (lock_list_cnt < 64); lock_list[lock_list_cnt++] = lock; } } lock_sema_down (&lock->semaphore, acquirer); } else { sema_down (&lock->semaphore); } // wait for the other to release lock->holder = acquirer; }
static ptid_t sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { ptid_t rtnval; ptid_t save_ptid; struct cleanup *old_chain; save_ptid = inferior_ptid; old_chain = save_inferior_ptid (); inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid)); if (PIDGET (inferior_ptid) == -1) inferior_ptid = procfs_first_available (); if (PIDGET (ptid) != -1) { ptid_t save_ptid = ptid; ptid = thread_to_lwp (ptid, -2); if (PIDGET (ptid) == -2) /* Inactive thread */ error ("This version of Solaris can't start inactive threads."); if (info_verbose && PIDGET (ptid) == -1) warning ("Specified thread %ld seems to have terminated", GET_THREAD (save_ptid)); } rtnval = procfs_ops.to_wait (ptid, ourstatus); if (ourstatus->kind != TARGET_WAITKIND_EXITED) { /* Map the LWP of interest back to the appropriate thread ID */ rtnval = lwp_to_thread (rtnval); if (PIDGET (rtnval) == -1) rtnval = save_ptid; /* See if we have a new thread */ if (is_thread (rtnval) && !ptid_equal (rtnval, save_ptid) && !in_thread_list (rtnval)) { printf_filtered ("[New %s]\n", target_pid_to_str (rtnval)); add_thread (rtnval); } } /* During process initialization, we may get here without the thread package being initialized, since that can only happen after we've found the shared libs. */ do_cleanups (old_chain); return rtnval; }
/* Returns the running thread. This is running_thread() plus a couple of sanity checks. See the big comment at the top of thread.h for details. */ struct thread * thread_current (void) { struct thread *t = running_thread (); /* Make sure T is really a thread. If either of these assertions fire, then your thread may have overflowed its stack. Each thread has less than 4 kB of stack, so a few big automatic arrays or moderate recursion can cause stack overflow. */ ASSERT (is_thread (t)); ASSERT (t->status == THREAD_RUNNING); return t; }
/* Transitions a blocked thread T to the ready-to-run state. This is an error if T is not blocked. (Use thread_yield() to make the running thread ready.) This function does not preempt the running thread. This can be important: if the caller had disabled interrupts itself, it may expect that it can atomically unblock a thread and update other data. */ void thread_unblock (struct thread *t) { enum intr_level old_level; ASSERT (is_thread (t)); old_level = intr_disable (); ASSERT (t->status == THREAD_BLOCKED); if(!thread_mlfqs) list_push_back (&ready_list, &t->elem); else list_push_back (&ready_mlfqs[t->priority], &t->elem); t->status = THREAD_READY; intr_set_level (old_level); }
void session_delete(struct session *session) { /* Tell the other side */ ASSERT_PTR(session); ASSERT_PTR(session->server); ASSERT_PTR(session->server->owner); assert(is_thread(session->server)); pd_release_clist(session->server->owner, session->clist); session_p_list_delete(session->owner_node); session_p_list_delete(session->server_node); session_p_list_delete(session->client_node); /* Then nuke everything */ session->magic = 0; free(session); }
static ptid_t lwp_to_thread (ptid_t lwp) { td_thrinfo_t ti; td_thrhandle_t th; td_err_e val; if (is_thread (lwp)) return lwp; /* It's already a thread id */ /* It's an lwp. Convert it to a thread id. */ if (!sol_thread_alive (lwp)) return pid_to_ptid (-1); /* defunct lwp */ val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th); if (val == TD_NOTHR) return pid_to_ptid (-1); /* thread must have terminated */ else if (val != TD_OK) error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val)); val = p_td_thr_validate (&th); if (val == TD_NOTHR) return lwp; /* libthread doesn't know about it; just return lwp */ else if (val != TD_OK) error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val)); val = p_td_thr_get_info (&th, &ti); if (val == TD_NOTHR) return pid_to_ptid (-1); /* thread must have terminated */ else if (val != TD_OK) error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val)); return BUILD_THREAD (ti.ti_tid, PIDGET (lwp)); }
static void sol_thread_store_registers (int regno) { thread_t thread; td_thrhandle_t thandle; td_err_e val; prgregset_t gregset; prfpregset_t fpregset; #if 0 int xregsize; caddr_t xregset; #endif if (!is_thread (inferior_ptid)) { /* LWP: pass the request on to procfs.c */ procfs_ops.to_store_registers (regno); return; } /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */ thread = GET_THREAD (inferior_ptid); val = p_td_ta_map_id2thr (main_ta, thread, &thandle); if (val != TD_OK) error ("sol_thread_store_registers: td_ta_map_id2thr %s", td_err_string (val)); if (regno != -1) { /* Not writing all the regs */ char old_value[MAX_REGISTER_SIZE]; /* Save new register value. */ regcache_collect (regno, old_value); val = p_td_thr_getgregs (&thandle, gregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getgregs %s", td_err_string (val)); val = p_td_thr_getfpregs (&thandle, &fpregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getfpregs %s", td_err_string (val)); /* Restore new register value. */ supply_register (regno, old_value); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_store_registers: td_thr_getxregsize %s", td_err_string (val)); if (val == TD_OK) { xregset = alloca (xregsize); val = td_thr_getxregs (&thandle, xregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getxregs %s", td_err_string (val)); } #endif } fill_gregset ((gdb_gregset_t *) &gregset, regno); fill_fpregset ((gdb_fpregset_t *) &fpregset, regno); val = p_td_thr_setgregs (&thandle, gregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_setgregs %s", td_err_string (val)); val = p_td_thr_setfpregs (&thandle, &fpregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_setfpregs %s", td_err_string (val)); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_store_registers: td_thr_getxregsize %s", td_err_string (val)); /* Should probably do something about writing the xregs here, but what are they? */ #endif }
static void sol_thread_fetch_registers (int regno) { thread_t thread; td_thrhandle_t thandle; td_err_e val; prgregset_t gregset; prfpregset_t fpregset; #if 0 int xregsize; caddr_t xregset; #endif if (!is_thread (inferior_ptid)) { /* LWP: pass the request on to procfs.c */ if (target_has_execution) procfs_ops.to_fetch_registers (regno); else orig_core_ops.to_fetch_registers (regno); return; } /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */ thread = GET_THREAD (inferior_ptid); if (thread == 0) error ("sol_thread_fetch_registers: thread == 0"); val = p_td_ta_map_id2thr (main_ta, thread, &thandle); if (val != TD_OK) error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s", td_err_string (val)); /* Get the integer regs */ val = p_td_thr_getgregs (&thandle, gregset); if (val != TD_OK && val != TD_PARTIALREG) error ("sol_thread_fetch_registers: td_thr_getgregs %s", td_err_string (val)); /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp are saved (by a thread context switch). */ /* And, now the fp regs */ val = p_td_thr_getfpregs (&thandle, &fpregset); if (val != TD_OK && val != TD_NOFPREGS) error ("sol_thread_fetch_registers: td_thr_getfpregs %s", td_err_string (val)); /* Note that we must call supply_{g fp}regset *after* calling the td routines because the td routines call ps_lget* which affect the values stored in the registers array. */ supply_gregset ((gdb_gregset_t *) &gregset); supply_fpregset ((gdb_fpregset_t *) &fpregset); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_fetch_registers: td_thr_getxregsize %s", td_err_string (val)); if (val == TD_OK) { xregset = alloca (xregsize); val = td_thr_getxregs (&thandle, xregset); if (val != TD_OK) error ("sol_thread_fetch_registers: td_thr_getxregs %s", td_err_string (val)); } #endif }
static ps_err_e rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr, char *buf, int size) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); if (is_thread (inferior_ptid) || /* A thread */ !target_thread_alive (inferior_ptid)) /* An lwp, but not alive */ inferior_ptid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ #if defined (__sparcv9) /* For Sparc64 cross Sparc32, make sure the address has not been accidentally sign-extended (or whatever) to beyond 32 bits. */ if (bfd_get_arch_size (exec_bfd) == 32) addr &= 0xffffffff; #endif while (size > 0) { int cc; /* FIXME: passing 0 as attrib argument. */ if (target_has_execution) cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, 0, &procfs_ops); else cc = orig_core_ops.to_xfer_memory (addr, buf, size, dowrite, 0, &core_ops); if (cc < 0) { if (dowrite == 0) print_sys_errmsg ("rw_common (): read", errno); else print_sys_errmsg ("rw_common (): write", errno); do_cleanups (old_chain); return PS_ERR; } else if (cc == 0) { if (dowrite == 0) warning ("rw_common (): unable to read at addr 0x%lx", (long) addr); else warning ("rw_common (): unable to write at addr 0x%lx", (long) addr); do_cleanups (old_chain); return PS_ERR; } size -= cc; buf += cc; } do_cleanups (old_chain); return PS_OK; }