您的位置:首页 > 文旅 > 美景 > 昆明网络推广哪家好_湛江自助建站模板_mac923水蜜桃923色号_java培训班学费一般多少

昆明网络推广哪家好_湛江自助建站模板_mac923水蜜桃923色号_java培训班学费一般多少

2025/7/13 22:53:22 来源:https://blog.csdn.net/qq_21551939/article/details/148841077  浏览:    关键词:昆明网络推广哪家好_湛江自助建站模板_mac923水蜜桃923色号_java培训班学费一般多少
昆明网络推广哪家好_湛江自助建站模板_mac923水蜜桃923色号_java培训班学费一般多少

声明:此处代码分析,来源与 nuttx 12.8.0版本。

在分析之前,需要一图镇楼。

/***************************************************************************** Name: nxsched_add_blocked** Description:*   This function adds a TCB to one of the blocked state task lists as*   inferred from task_state.** Input Parameters:*   btcb - Points to the TCB that is blocked*   task_state - identifies the state of the blocked task** Returned Value:*   None** Assumptions:* - The caller has established a critical section before*   calling this function.*****************************************************************************/void nxsched_add_blocked(FAR struct tcb_s *btcb, tstate_t task_state)
{FAR dq_queue_t *tasklist;/* Make sure that we received a valid blocked state */DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE &&task_state <= LAST_BLOCKED_STATE);/* Make sure the TCB's state corresponds to the list */btcb->task_state = task_state;/* Add the TCB to the blocked task list associated with this state. */tasklist = TLIST_BLOCKED(btcb);/* Determine if the task is to be added to a prioritized task list. */if (TLIST_ISPRIORITIZED(task_state)){/* Add the task to a prioritized list */nxsched_add_prioritized(btcb, tasklist);}else{/* Add the task to a non-prioritized list */dq_addlast((FAR dq_entry_t *)btcb, tasklist);}
}

显然,此函数的作用是依据task_state,将btcb放入阻塞队列。

既然是放入队列,首先是要找到具体的队列。

 /* Make sure the TCB's state corresponds to the list */btcb->task_state = task_state;/* Add the TCB to the blocked task list associated with this state. */tasklist = TLIST_BLOCKED(btcb);

TLIST_BLOCKED在sched.h中的定义如下。

/* List attribute flags */#define TLIST_ATTR_PRIORITIZED   (1 << 0) /* Bit 0: List is prioritized */
#define TLIST_ATTR_INDEXED       (1 << 1) /* Bit 1: List is indexed by CPU */
#define TLIST_ATTR_RUNNABLE      (1 << 2) /* Bit 2: List includes running tasks */
#define TLIST_ATTR_OFFSET        (1 << 3) /* Bit 3: Pointer of task list is offset */#define __TLIST_ATTR(s)          g_tasklisttable[s].attr
#define TLIST_ISPRIORITIZED(s)   ((__TLIST_ATTR(s) & TLIST_ATTR_PRIORITIZED) != 0)
#define TLIST_ISINDEXED(s)       ((__TLIST_ATTR(s) & TLIST_ATTR_INDEXED) != 0)
#define TLIST_ISRUNNABLE(s)      ((__TLIST_ATTR(s) & TLIST_ATTR_RUNNABLE) != 0)
#define TLIST_ISOFFSET(s)        ((__TLIST_ATTR(s) & TLIST_ATTR_OFFSET) != 0)#define __TLIST_HEAD(t) \(TLIST_ISOFFSET((t)->task_state) ? (FAR dq_queue_t *)((FAR uint8_t *)((t)->waitobj) + \(uintptr_t)g_tasklisttable[(t)->task_state].list) : g_tasklisttable[(t)->task_state].list)#ifdef CONFIG_SMP
#  define TLIST_HEAD(t,c) \((TLIST_ISINDEXED((t)->task_state)) ? (&(__TLIST_HEAD(t))[c]) : __TLIST_HEAD(t))
#  define TLIST_BLOCKED(t)       __TLIST_HEAD(t)
#else
#  define TLIST_HEAD(t)          __TLIST_HEAD(t)
#  define TLIST_BLOCKED(t)       __TLIST_HEAD(t)
#endif

在计算__TLIST_HEAD的时候,会有一个TLIST_ISOFFSET的判断。那什么队列会符合要求呢?根据定义,我们知道当g_tasklisttable[s].attr &TLIST_ATTR_OFFSET  != 0 就满足条件。

那,具体是什么队列呢?

static void tasklist_initialize(void)
{....../* TSTATE_WAIT_SEM */tlist[TSTATE_WAIT_SEM].list = (FAR void *)offsetof(sem_t, waitlist);tlist[TSTATE_WAIT_SEM].attr = TLIST_ATTR_PRIORITIZED |TLIST_ATTR_OFFSET;....../* TSTATE_WAIT_MQNOTEMPTY */tlist[TSTATE_WAIT_MQNOTEMPTY].list =(FAR void *)offsetof(struct mqueue_inode_s, cmn.waitfornotempty);tlist[TSTATE_WAIT_MQNOTEMPTY].attr = TLIST_ATTR_PRIORITIZED |TLIST_ATTR_OFFSET;/* TSTATE_WAIT_MQNOTFULL */tlist[TSTATE_WAIT_MQNOTFULL].list =(FAR void *)offsetof(struct mqueue_inode_s, cmn.waitfornotfull);tlist[TSTATE_WAIT_MQNOTFULL].attr = TLIST_ATTR_PRIORITIZED |TLIST_ATTR_OFFSET;......}

显然,信号量和消息队列会符合要求。

那么,

(FAR dq_queue_t *)((FAR uint8_t *)((t)->waitobj) + (uintptr_t)g_tasklisttable[(t)->task_state].list)具体指向那里呢?

为回答此问题,我们需要弄清楚对于信号量和消息队列来说,waitobj 和g_tasklisttable[(t)->task_state].list各指代什么意思。

对于g_tasklisttable[(t)->task_state].list,由上述代码可知,g_tasklisttable[TSTATE_WAIT_SEM].list 是 struct mqueue_inode_s结构体中,waitlist的偏移量。

struct sem_s
{......dq_queue_t waitlist;......}typedef struct sem_s sem_t;

对于g_tasklisttable[(t)->task_state].list,由上述代码可知,g_tasklisttable[TSTATE_WAIT_MQNOTEMPTY].list 是 sem_t结构体中,mn.waitfornotempty的偏移量。

struct mqueue_inode_s
{struct mqueue_cmn_s cmn;    /* Common prologue */......
}struct mqueue_cmn_s
{dq_queue_t waitfornotempty; /* Task list waiting for not empty */dq_queue_t waitfornotfull;  /* Task list waiting for not full */......
};

g_tasklisttable[TSTATE_WAIT_MQNOTFULL].list 同理。

waitobj的定义如下。

struct tcb_s
{..../* POSIX Semaphore and Message Queue Control Fields ***********************/FAR void *waitobj;                     /* Object thread waiting on        */......
}

那么,waitobj的赋值是什么呢?

int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,FAR struct mqueue_msg_s **rcvmsg,FAR const struct timespec *abstime,sclock_t ticks)
{......FAR struct tcb_s *rtcb = this_task();......rtcb->waitobj = msgq;......
}

对于信号量,waitobj同理。可见,waitobj指代的是具体等待的信号量或者消息队列。

那,为什么要这样呢?答案就藏在数据结构的定义里。

以sem_t来说,

struct sem_s
{......dq_queue_t waitlist;......}typedef struct sem_s sem_t;

有人可能会问,这能说明什么?这能说明,对于每一个sem_t实例来说,他们都有各自的队列。与之对应的g_tasklisttable.list中存放的是偏移值。

为什么这样设计呢? 

这样设计实现了所有阻塞类型的统一管理。

找到具体的队列之后,调用nxsched_add_prioritized或dq_addlast 将tcb_s加入队列。

除了,信号量和消息队列,还有哪些阻塞队列呢?

enum tstate_e
{......TSTATE_TASK_INACTIVE,       /* BLOCKED      - Initialized but not yet activated */TSTATE_WAIT_SEM,            /* BLOCKED      - Waiting for a semaphore */TSTATE_WAIT_SIG,            /* BLOCKED      - Waiting for a signal */
#if !defined(CONFIG_DISABLE_MQUEUE) || !defined(CONFIG_DISABLE_MQUEUE_SYSV)TSTATE_WAIT_MQNOTEMPTY,     /* BLOCKED      - Waiting for a MQ to become not empty. */TSTATE_WAIT_MQNOTFULL,      /* BLOCKED      - Waiting for a MQ to become not full. */
#endif
#ifdef CONFIG_LEGACY_PAGINGTSTATE_WAIT_PAGEFILL,       /* BLOCKED      - Waiting for page fill */
#endif
#ifdef CONFIG_SIG_SIGSTOP_ACTIONTSTATE_TASK_STOPPED,        /* BLOCKED      - Waiting for SIGCONT */
#endif......
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com