Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add fix timer race code #412

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open

add fix timer race code #412

wants to merge 23 commits into from

Conversation

M-iceberg
Copy link
Contributor

No description provided.

@M-iceberg
Copy link
Contributor Author

M-iceberg commented Nov 14, 2024

/azp run #Resolved

Copy link

azure-pipelines bot commented Nov 14, 2024

Azure Pipelines successfully started running 1 pipeline(s).

#Resolved

@M-iceberg
Copy link
Contributor Author

M-iceberg commented Nov 19, 2024

/azp run #Resolved

Copy link

azure-pipelines bot commented Nov 19, 2024

Azure Pipelines successfully started running 1 pipeline(s).

#Resolved

@@ -21,10 +21,13 @@ extern "C" {
#endif

typedef struct THREADPOOL_TAG THREADPOOL;
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
typedef struct TIMER_INSTANCE_TAG TIMER_INSTANCE;
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE; //todo: if this one is needed
Copy link
Contributor

@darobs darobs Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably remove TIMER_INSTANCE_HANDLE #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not removed, I can still see it.


MOCKABLE_FUNCTION(, int, threadpool_timer_restart, TIMER_INSTANCE_HANDLE, timer, uint32_t, start_delay_ms, uint32_t, timer_period_ms);
MOCKABLE_FUNCTION(, int, threadpool_timer_restart, THANDLE(TIMER_INSTANCE)*, timer, uint32_t, start_delay_ms, uint32_t, timer_period_ms);
Copy link
Contributor

@darobs darobs Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

)*

timer is just THANDLE(TIMER_INSTANCE), not THANDLE(TIMER_INSTANCE)* Same for line 92. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -1140,9 +1141,10 @@ TEST_FUNCTION(threadpool_timer_start_with_NULL_work_function_context_succeeds)
// arrange
THANDLE(THREADPOOL) threadpool = test_create_and_open_threadpool();

TIMER_INSTANCE_HANDLE timer_instance;
THANDLE(TIMER_INSTANCE) timer_instance = NULL;
Copy link
Contributor

@darobs darobs Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timer_instance = NULL

Do we have to assign this to be NULL for threadpool_timer_start to work? I can see this might be an annoyance when the timer is part of a struct, like it generally is. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will getting segmentation fault if not set this THANDLE to NULL

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The common pattern we have in the code that uses this is

typedef struct SOME_STRUCT_TAG
{
//  ...
THANDLE(TIMER_INSTANCE) timer;
// ...
} SOME_STRUCT;

// then in the "_create" function:
SOME_STRUCT_HANDLE  result = (SOME_STRUCT_HANDLE)malloc(sizeof(SOME_STRUCT);
threadpool_timer_start(threadpool, start_delay, period, test_work_function, context, &result->timer);

The timer is being passed in uninitialized, and so requiring it to be initialized in the test implies that the above pattern will need to change. BTW, this comment goes along with using THANDLE_INITIALIZE_MOVE instead of THANDLE_MOVE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modified to initialize_move

threadpool_internal_set_timer(tp_timer, start_delay_ms, timer_period_ms);

/* Codes_SRS_THREADPOOL_WIN32_42_009: [ threadpool_timer_start shall return the allocated handle in timer_handle. ]*/
THANDLE_MOVE(TIMER_INSTANCE)(timer_handle, &timer_temp);
Copy link
Contributor

@darobs darobs Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THANDLE_MOVE(TIMER_INSTANCE)(timer_handle, &timer_temp);

Would THANDLE_INITIALIZE_MOVE make more sense here? #Resolved

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for Linux?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -18,8 +18,7 @@
threadpool_schedule_work, \
threadpool_timer_start, \
threadpool_timer_restart, \
threadpool_timer_cancel, \
threadpool_timer_destroy \
threadpool_timer_cancel
) \
Copy link
Contributor

@darobs darobs Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build failed, missing \ at the end of this line #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Copy link

azure-pipelines bot commented Nov 19, 2024

No pipelines are associated with this pull request.

#Resolved

1 similar comment
Copy link

azure-pipelines bot commented Nov 19, 2024

No pipelines are associated with this pull request.

#Resolved

@M-iceberg
Copy link
Contributor Author

M-iceberg commented Nov 19, 2024

/azp run #Resolved

Copy link

azure-pipelines bot commented Nov 19, 2024

Azure Pipelines successfully started running 1 pipeline(s).

#Resolved

@M-iceberg
Copy link
Contributor Author

M-iceberg commented Nov 19, 2024

/azp run #Resolved

Copy link

azure-pipelines bot commented Nov 19, 2024

Azure Pipelines successfully started running 1 pipeline(s).

#Resolved

@@ -21,10 +21,13 @@ extern "C" {
#endif

typedef struct THREADPOOL_TAG THREADPOOL;
typedef struct TIMER_INSTANCE_TAG TIMER_INSTANCE;
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
Copy link
Member

@dcristoloveanu dcristoloveanu Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIMER_INSTANCE_HANDLE

Who uses the TIMER_INSTANCE_HANDLE? I am imagining that after this change there should be only one, right? #Resolved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or are there more PRs planned? If so, we should add a comment explaining that, otherwise it is sort of confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the timer_instance_handle, not using anymore

Copy link

azure-pipelines bot commented Dec 19, 2024

Azure Pipelines successfully started running 1 pipeline(s).

#Resolved

@M-iceberg
Copy link
Contributor Author

M-iceberg commented Dec 19, 2024

/azp run #Resolved

Copy link

azure-pipelines bot commented Dec 19, 2024

Azure Pipelines successfully started running 1 pipeline(s).

#Resolved

@@ -39,13 +39,13 @@ MOCKABLE_FUNCTION(, int, threadpool_schedule_work_item, THANDLE(THREADPOOL), thr

MOCKABLE_FUNCTION(, int, threadpool_schedule_work, THANDLE(THREADPOOL), threadpool, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context);

MOCKABLE_FUNCTION(, int, threadpool_timer_start, THANDLE(THREADPOOL), threadpool, uint32_t, start_delay_ms, uint32_t, timer_period_ms, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context, TIMER_INSTANCE_HANDLE*, timer_handle);
MOCKABLE_FUNCTION(, int, threadpool_timer_start, THANDLE(THREADPOOL), threadpool, uint32_t, start_delay_ms, uint32_t, timer_period_ms, THREADPOOL_WORK_FUNCTION, work_function, void*, work_function_context, TIMER **, timer_handle);
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIMER **

This is not what is in the header.
This should be a copy/paste of what we have in the threadpool.h #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done updated this md

typedef struct THREADPOOL_WORK_ITEM_TAG THREADPOOL_WORK_ITEM;
typedef void (*THREADPOOL_WORK_FUNCTION)(void* context);

THANDLE_TYPE_DECLARE(TIMER);
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIMER

I think this should be named THREADPOOL_TIMER. To be in sync with THREADPOOL_WORK_FUNCTION #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -21,10 +21,12 @@ extern "C" {
#endif

typedef struct THREADPOOL_TAG THREADPOOL;
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
typedef struct TIMER_TAG TIMER;
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have this close to the THANDLE_TYPE_DECLARE, so that it is not intermingled with the work item stuff? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -65,7 +65,7 @@ The guard prevents any work from happening, but the event callback can still be

```C
typedef struct THREADPOOL_TAG THREADPOOL;
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
typedef struct TIMER_TAG* TIMER *;
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not what is in the header ... #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

void real_threadpool_timer_cancel(TIMER_INSTANCE_HANDLE timer);
void real_threadpool_timer_destroy(TIMER_INSTANCE_HANDLE timer);
int real_threadpool_timer_start(THANDLE(THREADPOOL) threadpool, uint32_t start_delay_ms, uint32_t timer_period_ms, THREADPOOL_WORK_FUNCTION work_function, void* work_function_context, THANDLE(TIMER)* timer_handle);
int real_threadpool_timer_restart(THANDLE(TIMER) timer, uint32_t start_delay_ms, uint32_t timer_period_ms);
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint32_t

Suggest including stdint.h #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@@ -14,7 +14,6 @@
#define threadpool_timer_start real_threadpool_timer_start
#define threadpool_timer_restart real_threadpool_timer_restart
#define threadpool_timer_cancel real_threadpool_timer_cancel
#define threadpool_timer_destroy real_threadpool_timer_destroy
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat-o #Resolved

} THREADPOOL_TASK;

typedef struct THREADPOOL_WORK_ITEM_TAG
{
THREADPOOL_WORK_FUNCTION work_function;
void* work_function_ctx;
} THREADPOOL_WORK_ITEM, *THREADPOOL_WORK_ITEM_HANDLE;
volatile_atomic int32_t pending_work_item_count;
} THREADPOOL_WORK_ITEM, * THREADPOOL_WORK_ITEM_HANDLE;
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was removed by Nishikant, so it was likely added back by mistake during merge. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


typedef struct THREADPOOL_TASK_TAG
{
volatile_atomic int32_t task_state;
THREADPOOL_WORK_FUNCTION work_function;
void* work_function_ctx;
volatile uint32_t pending_api_calls;
volatile_atomic int32_t *pending_work_item_count_ptr;
} THREADPOOL_TASK;
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was removed by Nishikant also. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

// and manage each state as in-use or not. That way the timer data allocation is not dependent on threadpool_timer_start/destroy.
// To reproduce this problem, create a large number of threads that delete the timer at the same time it is due to expire and remove the pause
// above.
}
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mentions a small wait that does not exist any longer. I think this comment is now obsolete? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted

{
LogErrorNo("Failure calling timer_create.");
LogError("srw_lock_ll_init failed");
}
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect a Codes for "if any error occurrs then threadpool_timer_start shall fail and return a non zero value. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

{
int result;
if (timer == NULL)
{
/* Codes_SRS_THREADPOOL_LINUX_07_064: [ If timer is NULL, threadpool_timer_restart shall fail and return a non-zero value. ]*/
LogError("Invalid args: TIMER_INSTANCE_HANDLE timer = %p, uint32_t start_delay_ms = %" PRIu32 ", uint32_t timer_period_ms = %" PRIu32 "",
LogError("Invalid args: TIMER * timer = %p, uint32_t start_delay_ms = %" PRIu32 ", uint32_t timer_period_ms = %" PRIu32 "",
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIMER *

Signature above is with THANLDE(TIMER) #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
if (timer == NULL)
{
/* Codes_SRS_THREADPOOL_LINUX_07_068: [ If timer is NULL, threadpool_timer_cancel shall fail and return. ]*/
LogError("Invalid args: TIMER_INSTANCE_HANDLE timer = %p", timer);
LogError("Invalid args: TIMER * timer = %p", timer);
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIMER *

This too: THANDLE(TOIMER) #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@dcristoloveanu
Copy link
Member

#include <string.h>

Didn't we say we should have only one int test file?


Refers to: linux/tests/threadpool_linux_int/threadpool_linux_int.c:8 in 438a45a. [](commit_id = 438a45a, deletion_comment = False)

@@ -12,7 +12,7 @@ It uses the PTP_POOL associated with the execution engine passed as argument to

```c
typedef struct THREADPOOL_TAG THREADPOOL;
typedef struct TIMER_INSTANCE_TAG* TIMER_INSTANCE_HANDLE;
typedef struct TIMER_TAG* TIMER *;
Copy link
Member

@dcristoloveanu dcristoloveanu Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ER_TAG* TIMER *;

Looks off comparing to the header #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Copy link

azure-pipelines bot commented Dec 23, 2024

No pipelines are associated with this pull request.

#Resolved

4 similar comments
Copy link

azure-pipelines bot commented Dec 23, 2024

No pipelines are associated with this pull request.

#Resolved

Copy link

azure-pipelines bot commented Dec 23, 2024

No pipelines are associated with this pull request.

#Resolved

Copy link

azure-pipelines bot commented Dec 23, 2024

No pipelines are associated with this pull request.

#Resolved

Copy link

azure-pipelines bot commented Dec 23, 2024

No pipelines are associated with this pull request.

#Resolved

@M-iceberg
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@M-iceberg
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants