scope of pthread function arguments

Viewed 188

Here's the signature of pthread_setschedparam:

#include <pthread.h>

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);

Will this piece of code result in unexpected behavior:

void schedule(const thread &t, int policy, int priority) {
    sched_param params;
    params.sched_priority = priority;
    pthread_setschedparam(t.native_handle(), policy, &params);
}

It is completely unclear if the scope of params needs to be broader than the function call alone. When I see a function that takes in a pointer, it suggests (to me at least) that it's asking for ownership of it. Is this signature just badly designed? Should "sched_params params" live on the heap? Does it need to outlive the thread to stay valid? Can it be deleted?

I have no idea.

Thanks!

2 Answers

pthread_setschedparam sets the scheduling policy for the given thread. The parameters need not be alive after the call.

If the lifetime of the last argument mattered (as you put, if pthread_setschedparam takes ownership of it), it would have been explicitly documented so. But it's not in POSIX documentation pthread_setschedparam .

The probable reason why it takes a pointer (instead of value) is that it's less expensive to pass a pointer than a struct.

When I see a function that takes in a pointer, it suggests (to me at least) that it's asking for ownership of it.

I don't jump straight there when I see a function that accepts a pointer parameter, and I don't think you should, either. Although it is important to be aware of the possibility, and you do well to look for documentation, there is a variety of reasons for a function to take a pointer parameter, among them:

  • the function accepts arrays via the parameter. This is surely the most common reason.
  • the function wants to modify an object specified to it by the caller (via the pointer). This is probably the second most common reason.
  • the function accepts a pointer to a structure or union of large or potentially-large size to lighten the function-call overhead
  • the function accepts a pointer to a structure or union because it conforms to interface conventions that accommodate ancient C compilers that did not accept structures and unions as arguments. This was normal for early C compilers, as it's the way the language was originally specified:

    [T]he only operations you can perform on a structure are take its address with & and access one of its members. [... Structures] can not be passed to or returned from functions. [...] Pointers to structures do not suffer these limitations[.]

    (Kernighan & Ritchie, The C Programming Language, 1st ed., section 6.2)

    Standard C does not have those restrictions, but their effect can still be felt in some places.

That the function expects to take (and typically reassign) responsibility for freeing dynamically-allocated space to which the pointer points, or that it otherwise intends to make a copy of the pointer that survives the function's return, are way down the list. If a function intends to do one of those things, then I fully expect its documentation to indicate so in some manner.

Is this signature just badly designed?

No, I think its design is prompted by one or both of the latter two points from my list.

Should "sched_params params" live on the heap?

I would not expect that to be a requirement.

Does it need to outlive the thread to stay valid? Can it be deleted?

I do not think it needs to outlive the thread whose properties are set. In addition to my general interpretation of the interface, I read (weak) support for that position in the wording of the function's POSIX specification:

The pthread_setschedparam() function shall set the scheduling policy and associated scheduling parameters for the thread whose thread ID is given by thread to the policy and associated parameters provided in policy and param, respectively.

(POSIX specification for pthread_setscheduleparam(); emphasis added)

The "provided in" language indicates to me (again, weakly) that the function uses the contents of the pointed-to structure, not the structure itself.

Related