[CRIU] [PATCH v3 14/26] files: Implement {set,get}_fds_event()

Kirill Tkhai ktkhai at virtuozzo.com
Tue Dec 6 09:59:05 PST 2016


On 06.12.2016 20:39, Pavel Emelyanov wrote:
> On 12/05/2016 05:09 PM, Kirill Tkhai wrote:
>> The idea is symilar to kernel's wake_up() and wait_event().
>> One task needs some event. It checks the event has not
>> happened yet (fle hasn't received, unix peer hasn't bound, etc)
>> and calls get_fds_event(). Other task makes the event
>> (sends a fle, binds the peer to a name, etc) and calls set_fds_event().
>>
>> So, while there is no an event, the first task is sleeping,
>> and the second wakes it up later:
>>
>> Task A:      if (!socket_bound)
>>                      get_fds_event(); /* sleep */
> 
> get? There's no such thing in the patch :)

Ah, yeah
 
>> Task B:      bind_socket();
>>              set_fds_event();         /* wake up */
>>
>> v2: Do not wait for foreign transport sock is ready,
>> as it's guarantied by we create it before CR_STATE_FORKING
>>
>> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
>> ---
>>  criu/files.c          |   34 ++++++++++++++++++++++++++++++++++
>>  criu/include/files.h  |    2 ++
>>  include/common/lock.h |    5 +++++
>>  3 files changed, 41 insertions(+)
>>
>> diff --git a/criu/files.c b/criu/files.c
>> index 4039803..69a43c6 100644
>> --- a/criu/files.c
>> +++ b/criu/files.c
>> @@ -1631,3 +1631,37 @@ int open_transport_socket(void)
>>  
>>  	return 0;
>>  }
>> +
>> +int set_fds_event(pid_t virt)
>> +{
>> +	struct pstree_item *item;
>> +	int old, st;
>> +
>> +	item = pstree_item_by_virt(virt);
>> +	BUG_ON(!item);
>> +
>> +	/* Set FDS_EVENT and wake up if need */
>> +	do {
>> +		old = futex_get(&item->task_st);
>> +		if (old & FDS_EVENT)
>> +			break;
>> +		st = atomic_cmpxchg(&item->task_st.raw, old, old | FDS_EVENT);
>> +	} while (st != old);
>> +
>> +	if (!(old & FDS_EVENT))
>> +		futex_wake(&item->task_st);
>> +	return 0;
>> +}
>> +
>> +int wait_fds_event(void)
>> +{
>> +	int old, st;
>> +
>> +	futex_wait_if_cond(&current->task_st, FDS_EVENT, &);
>> +	do {
>> +		old = futex_get(&current->task_st);
>> +		st = atomic_cmpxchg(&current->task_st.raw, old, old & ~FDS_EVENT);
>> +	} while (st != old);
>> +
>> +	return 0;
>> +}
>> diff --git a/criu/include/files.h b/criu/include/files.h
>> index 5719004..7fdb3cf 100644
>> --- a/criu/include/files.h
>> +++ b/criu/include/files.h
>> @@ -193,5 +193,7 @@ int dup_fle(struct pstree_item *task, struct fdinfo_list_entry *ple,
>>  	    int fd, unsigned flags);
>>  
>>  extern int open_transport_socket(void);
>> +extern int set_fds_event(pid_t virt);
>> +extern int wait_fds_event(void);
>>  
>>  #endif /* __CR_FILES_H__ */
>> diff --git a/include/common/lock.h b/include/common/lock.h
>> index afc0f96..2261cf9 100644
>> --- a/include/common/lock.h
>> +++ b/include/common/lock.h
>> @@ -78,6 +78,11 @@ static inline void futex_set_and_wake(futex_t *f, uint32_t v)
>>  	LOCK_BUG_ON(sys_futex((uint32_t *)&f->raw.counter, FUTEX_WAKE, INT_MAX, NULL, NULL, 0) < 0);
>>  }
>>  
>> +static inline void futex_wake(futex_t *f)
>> +{
>> +	LOCK_BUG_ON(sys_futex((uint32_t *)&f->raw.counter, FUTEX_WAKE, INT_MAX, NULL, NULL, 0) < 0);
>> +}
>> +
>>  /* Mark futex @f as wait abort needed and wake up all waiters */
>>  static inline void futex_abort_and_wake(futex_t *f)
>>  {
>>
>> .
>>
> 


More information about the CRIU mailing list