Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 40 additions & 27 deletions src/hal/hal_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2388,7 +2388,6 @@ int hal_export_funct(const char *name, void (*funct) (void *, long),
int cmp;
hal_funct_t *new, *fptr;
hal_comp_t *comp;
char buf[HAL_NAME_LEN + 1];

if (hal_data == NULL) {
rtapi_print_msg(RTAPI_MSG_ERR,
Expand Down Expand Up @@ -2486,25 +2485,25 @@ int hal_export_funct(const char *name, void (*funct) (void *, long),
halpr_mutex_release();

/* create a pin with the function's runtime in it */
if (hal_pin_s32_newf(HAL_OUT, &(new->runtime), comp_id,"%s.time",name)) {
rtapi_print_msg(RTAPI_MSG_ERR,
"HAL: ERROR: fail to create pin '%s.time'\n", name);
return -EINVAL;
if (hal_pin_new_si32(comp_id, HAL_OUT, &(new->runtime), 0, "%s.time", name) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "HAL: ERROR: fail to create pin '%s.time'\n", name);
return -EINVAL;
}
*(new->runtime) = 0;

/* note that failure to successfully create the following params
does not cause the "export_funct()" call to fail - they are
for debugging and testing use only */
/* create a parameter with the function's maximum runtime in it */
rtapi_snprintf(buf, sizeof(buf), "%s.tmax", name);
new->maxtime = 0;
hal_param_s32_new(buf, HAL_RW, &(new->maxtime), comp_id);
if(hal_param_new_si32(comp_id, HAL_RW, &(new->maxtime), 0, "%s.tmax", name) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "HAL: ERROR: fail to create param '%s.tmax'\n", name);
return -EINVAL;
}

/* create a parameter with the function's maximum runtime in it */
rtapi_snprintf(buf, sizeof(buf), "%s.tmax-increased", name);
new->maxtime_increased = 0;
hal_param_bit_new(buf, HAL_RO, &(new->maxtime_increased), comp_id);
if(hal_param_new_bool(comp_id, HAL_RO, &(new->maxtime_increased), 0, "%s.tmax-increased", name) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "HAL: ERROR: fail to create param '%s.tmax-increased'\n", name);
return -EINVAL;
}

return 0;
}
Expand Down Expand Up @@ -2652,6 +2651,13 @@ int hal_create_thread(const char *name, unsigned long period_nsec, int uses_fp)
/* insert new structure at head of list */
new->next_ptr = hal_data->thread_list_ptr;
hal_data->thread_list_ptr = SHMOFF(new);

// The counter that increases monotonically once every thread loop cycle.
// This is a 'fast' counter with normal access semantics. Separated from
// the param 'threadbeat' so it only needs to write _once_ to volatile
// memory instead of a very expensive read-modify-write cycle.
new->beatcnt = 0;

/* done, release mutex */
halpr_mutex_release();

Expand All @@ -2663,20 +2669,26 @@ int hal_create_thread(const char *name, unsigned long period_nsec, int uses_fp)
return new->comp_id;
}

rtapi_snprintf(buf, sizeof(buf), "%s.tmax", new->name);
new->maxtime = 0;
if (hal_param_s32_new(buf, HAL_RW, &(new->maxtime), new->comp_id)) {
if ((retval = hal_param_new_si32(new->comp_id, HAL_RW, &(new->maxtime), 0, "%s.tmax", new->name)) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"HAL: ERROR: fail to create param '%s.tmax'\n", new->name);
return -EINVAL;
return retval;
}

if (hal_pin_s32_newf(HAL_OUT, &(new->runtime), new->comp_id,"%s.time",new->name)) {
if ((retval = hal_pin_new_si32(new->comp_id, HAL_OUT, &(new->runtime), 0, "%s.time", new->name)) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"HAL: ERROR: fail to create pin '%s.time'\n", new->name);
return -EINVAL;
return retval;
}
*(new->runtime) = 0;

// A pin that increases monotonically once every thread loop cycle.
// This way we can detect when a RT-cycle was completed from non-RT
// and prevent racy indeterministic sleep() constructs.
if((retval = hal_pin_new_sint(new->comp_id, HAL_OUT, &(new->threadbeat), 0, "%s.threadbeat", new->name)) < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "HAL: ERROR: fail to create pin '%s.threadbeat'\n", new->name);
return retval;
}

hal_ready(new->comp_id);

rtapi_print_msg(RTAPI_MSG_DBG, "HAL: thread created\n");
Expand Down Expand Up @@ -3647,23 +3659,24 @@ static void thread_task(void *arg)
/* point to function structure */
funct = SHMPTR(funct_entry->funct_ptr);
/* update execution time data */
*(funct->runtime) = (hal_s32_t)(end_time - start_time);
if ( *(funct->runtime) > funct->maxtime) {
funct->maxtime = *(funct->runtime);
funct->maxtime_increased = 1;
rtapi_s32 runtime = hal_set_si32(funct->runtime, end_time - start_time);
if ( runtime > hal_get_si32(funct->maxtime)) {
hal_set_si32(funct->maxtime, runtime);
hal_set_bool(funct->maxtime_increased, 1);
} else {
funct->maxtime_increased = 0;
hal_set_bool(funct->maxtime_increased, 0);
}
/* point to next next entry in list */
funct_entry = SHMPTR(funct_entry->links.next);
/* prepare to measure time for next funct */
start_time = end_time;
}
/* update thread execution time */
*(thread->runtime) = (hal_s32_t)(end_time - thread_start_time);
if ( *(thread->runtime) > thread->maxtime) {
thread->maxtime = *(thread->runtime);
rtapi_s32 runtime = hal_set_si32(thread->runtime, end_time - thread_start_time);
if ( runtime > hal_get_si32(thread->maxtime)) {
hal_set_si32(thread->maxtime, runtime);
}
hal_set_sint(thread->threadbeat, ++thread->beatcnt);
}
/* wait until next period */
rtapi_wait();
Expand Down
20 changes: 14 additions & 6 deletions src/hal/hal_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
*/

#define HAL_KEY 0x48414C32 /* key used to open HAL shared memory */
#define HAL_VER 0x00000013 /* version code */
#define HAL_VER 0x00000014 /* version code */
#define HAL_SIZE (2*256*4096)

/* These pointers are set by hal_init() to point to the shmem block
Expand Down Expand Up @@ -396,9 +396,12 @@ struct hal_funct_t {
int users; /* number of threads using function */
void *arg; /* argument for function */
void (*funct) (void *, long); /* ptr to function code */
hal_s32_t* runtime; /* (pin) duration of last run, in CPU cycles */
hal_s32_t maxtime; /* (param) duration of longest run, in CPU cycles */
hal_bit_t maxtime_increased; /* (param) on last call, maxtime increased */
// IMPORTANT: The pins and params are valid as seen from the context that
// created them. For uspace that is rtapi_app and in the kernel it is the
// kernel's module context.
hal_sint_t runtime; /* (pin) duration of last run, in CPU cycles */
hal_sint_t maxtime; /* (param) duration of longest run, in CPU cycles */
hal_bool_t maxtime_increased; /* (param) on last call, maxtime increased */
char name[HAL_NAME_LEN + 1]; /* function name */
};

Expand All @@ -417,8 +420,13 @@ struct hal_thread_t {
long int period; /* period of the thread, in nsec */
int priority; /* priority of the thread */
int task_id; /* ID of the task that runs this thread */
hal_s32_t* runtime; /* (pin) duration of last run, in ns */
hal_s32_t maxtime; /* (param) duration of longest run, in ns */
// IMPORTANT: The pins and params are valid as seen from the context that
// created them. For uspace that is rtapi_app and in the kernel it is the
// kernel's module context.
hal_sint_t runtime; /* (pin) duration of last run, in ns */
hal_sint_t maxtime; /* (param) duration of longest run, in ns */
hal_sint_t threadbeat; /* (pin) visible monotonic loop beat counter */
rtapi_sint beatcnt; /* Thread monotonic increasing loop beat counter (so we don't need to read/write volatile) */
hal_list_t funct_list; /* list of functions to run */
hal_list_t init_funct_list; /* list of init functions, run once before first cyclic cycle */
int init_done; /* 0 = init pending, 1 = init cycle has executed */
Expand Down
2 changes: 1 addition & 1 deletion src/hal/utils/halrmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1842,7 +1842,7 @@ static void getThreadInfo(char *pattern, connectionRecType *context)
(unsigned int)tptr->period,
(tptr->uses_fp ? "YES" : "NO "),
runtime_pin_value,
(unsigned int)tptr->maxtime);
(unsigned int)hal_get_si32(tptr->maxtime));
sockWrite(context);
list_root = &(tptr->funct_list);
list_entry = list_next(list_root);
Expand Down
Loading