Effective use of synchronization in macOS kernel extension

I use KPI synchronization in my macOS kernel extension to make sure that one function is fully executed before the other function runs (both functions are executed in different threads, of course).

These are the synchronization methods:

msleep(void *channel,lck_mtx_t *mtx,int priority,const char *wmesg,  struct  timespec *timeout);
wakeup(void *channel);

So, channel- this is a pointer to a logical value representing the first function, fully executed.

Here is my implementation in the first function:

OSIncrementAtomic(channel);
wakeup(channel);

And for another function, I'm waiting for it to be installed channel:

msleep(channel, NULL, 0, "", ts);

However, in the event that the first function is completed before the second (which is the usual case), I will wait for the shell to time out tsfor the vein.

My question is: is there a way to skip msleepin case it wakeuphas already happened?

thank,

+4
2

lck_mtx_sleep_deadline() ( IOLockSleepDeadline()) . , :

  • ( ?)
  • , lck_mtx_sleep_deadline()

2 + 3 a while() .

" ":

  • ( )
  • . (, thread_wakeup_prim((event_t) event, oneThread, THREAD_AWAKENED);)
  • .

, msleep()/wakeup() , API.

+2

msleep.

-, channel - , " "; , . , , .. msleep. . , msleep wakeup, Mach > , msleep/wakeup.

, @mrdvlpr , msleep , . mtx=NULL, , wakeup . wakeup wakeup_once, NULL.

, msleep - XNU :

lck_grp_t *lck_grp;
lck_mtx_t *lck_mtx;

lck_grp = lck_grp_alloc_init("com.example.mslpex", LCK_GRP_ATTR_NULL);
if (!lck_grp)
    /* handle failure */
lck_mtx = lck_mtx_alloc_init(lck_grp, LCK_ATTR_NULL);
if (!lck_mtx)
    /* handle failure */

/* ... */

lck_mtx_lock(lck_mtx);
error = msleep(channel, lck_mtx, pri|PDROP, "mslpex", NULL);
if (error)
    /* handle failure */
else
    /* handle success */

/* ... */

lck_mtx_free(lck_mtx, lck_grp);
lck_grp_free(lck_grp);

:

wakeup(channel);

, , - msleep , wakeup .

0

Source: https://habr.com/ru/post/1688530/


All Articles