[PATCH 2/4] Validate acc_device_t uses
Thomas Schwinge
thomas@codesourcery.com
Tue Dec 3 12:14:00 GMT 2019
Hi Frederik!
You once had this patch separate, but then merged into the upstream
submission of 'acc_get_property'; let's please keep this separate.
With changes as indicated below, please commit this to trunk (without the
three hunks related to 'acc_get_property', of course; these will then go
into the 'acc_get_property' changes, don't need to re-post
'acc_get_property' because of that). To record the review effort, please
include "Reviewed-by: Thomas Schwinge <thomas@codesourcery.com>" in the
commit log, see <https://gcc.gnu.org/wiki/Reviewed-by>.
On 2019-11-13T16:32:13+0100, Frederik Harwath <frederik@codesourcery.com> wrote:
> Check that function arguments of type acc_device_t
> are valid enumeration values in all publicly visible
> functions.
>
> libgomp/
> * oacc-init.c (acc_known_device_type): Add function.
> (unknown_device_type_error): Add function.
> (name_of_acc_device_t): Change to call unknown_device_type_error
> on unknown type.
> (resolve_device): Use acc_known_device_type.
> (acc_init): Fail if acc_device_t argument is not valid.
> (acc_shutdown): Likewise.
> (acc_get_num_devices): Likewise.
> (acc_set_device_type): Likewise.
> (acc_get_device_num): Likewise.
> (acc_set_device_num): Likewise.
> (get_property_any): Likewise.
> (acc_get_property): Likewise.
> (acc_get_property_string): Likewise.
> (acc_on_device): Likewise.
> (goacc_save_and_set_bind): Likewise.
Proper indenting.
> --- a/libgomp/oacc-init.c
> +++ b/libgomp/oacc-init.c
> @@ -93,6 +93,21 @@ get_openacc_name (const char *name)
> return name;
> }
>
> +
> +static int
> +acc_known_device_type (acc_device_t __arg)
No leading underscores ('__arg') in implementation files. (Or, just us
'd' as often/always done elsewhere in this file.)
Often, such inquiry functions are post-fixed with '_p' (but not always).
Can drop the 'acc_' prefix, as this is an internal ('static') function.
Return type should be 'bool'.
> +{
> + return __arg >= 0 && __arg < _ACC_device_hwm;
> +}
> +
> +
> +static void
> +unknown_device_type_error (unsigned invalid_type)
I suggest this should take an 'acc_device_t, and then cast to
'(unsigned)' when used here:
> +{
> + gomp_fatal ("unknown device type %u", invalid_type);
> +}
> +
> +
> static const char *
> name_of_acc_device_t (enum acc_device_t type)
> {
Also, move the two new functions before 'get_openacc_name'.
Generally, does usage of these functions obsolete some existing usage of
'acc_dev_num_out_of_range'? (OK to address later.)
> @@ -103,8 +118,9 @@ name_of_acc_device_t (enum acc_device_t type)
> case acc_device_host: return "host";
> case acc_device_not_host: return "not_host";
> case acc_device_nvidia: return "nvidia";
> - default: gomp_fatal ("unknown device type %u", (unsigned) type);
> + default: unknown_device_type_error(type);
Missing space before '('. Not just here, but generally.
> }
> + return 0; /** Never reached **/
> }
As done elsewhere in libgomp, instead of that 'return' plus comment, just
call '__builtin_unreachable ()'.
> @@ -123,7 +139,7 @@ resolve_device (acc_device_t d, bool fail_is_error)
> if (goacc_device_type)
> {
> /* Lookup the named device. */
> - while (++d != _ACC_device_hwm)
> + while (acc_known_device_type (++d))
> if (dispatchers[d]
> && !strcasecmp (goacc_device_type,
> get_openacc_name (dispatchers[d]->name))
> @@ -147,7 +163,7 @@ resolve_device (acc_device_t d, bool fail_is_error)
>
> case acc_device_not_host:
> /* Find the first available device after acc_device_not_host. */
> - while (++d != _ACC_device_hwm)
> + while (acc_known_device_type (++d))
> if (dispatchers[d] && dispatchers[d]->get_num_devices_func () > 0)
> goto found;
> if (d_arg == acc_device_default)
> @@ -168,7 +184,7 @@ resolve_device (acc_device_t d, bool fail_is_error)
> break;
>
> default:
> - if (d > _ACC_device_hwm)
> + if (!acc_known_device_type (d))
> {
> if (fail_is_error)
> goto unsupported_device;
Note that this had 'd > _ACC_device_hwm', not '>=' as it now does, that
is, previously didn't reject 'd == _ACC_device_hwm' but now does -- but I
suppose this was an (minor) bug that existed before, so OK to change as
you did?
> @@ -328,7 +344,6 @@ acc_shutdown_1 (acc_device_t d)
> gomp_unload_device (acc_dev);
> gomp_mutex_unlock (&acc_dev->lock);
> }
> -
> gomp_mutex_lock (&goacc_thread_lock);
>
> /* Free target-specific TLS data and close all devices. */
> @@ -494,7 +509,6 @@ goacc_attach_host_thread_to_device (int ord)
> thr->api_info = NULL;
> /* Initially, all callbacks for all events are enabled. */
> thr->prof_callbacks_enabled = true;
> -
> thr->target_tls
> = acc_dev->openacc.create_thread_data_func (ord);
> }
Please avoid doing such unrelated changes.
> @@ -505,12 +519,15 @@ goacc_attach_host_thread_to_device (int ord)
> void
> acc_init (acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error(d);
> +
> gomp_init_targets_once ();
>
> gomp_mutex_lock (&acc_device_lock);
> cached_base_dev = acc_init_1 (d, acc_construct_runtime_api, 0);
> gomp_mutex_unlock (&acc_device_lock);
> -
> +
> goacc_attach_host_thread_to_device (-1);
> }
>
> @@ -519,6 +536,9 @@ ialias (acc_init)
> void
> acc_shutdown (acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error(d);
> +
> gomp_init_targets_once ();
>
> gomp_mutex_lock (&acc_device_lock);
> @@ -533,6 +553,9 @@ ialias (acc_shutdown)
> int
> acc_get_num_devices (acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error(d);
> +
> int n = 0;
> struct gomp_device_descr *acc_dev;
>
> @@ -564,6 +587,9 @@ ialias (acc_get_num_devices)
> void
> acc_set_device_type (acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error(d);
> +
> struct gomp_device_descr *base_dev, *acc_dev;
> struct goacc_thread *thr = goacc_thread ();
>
> @@ -648,12 +674,12 @@ ialias (acc_get_device_type)
> int
> acc_get_device_num (acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error(d);
> +
> const struct gomp_device_descr *dev;
> struct goacc_thread *thr = goacc_thread ();
>
> - if (d >= _ACC_device_hwm)
> - gomp_fatal ("unknown device type %u", (unsigned) d);
> -
> acc_prof_info prof_info;
> acc_api_info api_info;
> bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
> @@ -683,6 +709,9 @@ ialias (acc_get_device_num)
> void
> acc_set_device_num (int ord, acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error(d);
> +
> struct gomp_device_descr *base_dev, *acc_dev;
> int num_devices;
>
> @@ -806,6 +844,9 @@ ialias (acc_get_property_string)
> int __attribute__ ((__optimize__ ("O2")))
> acc_on_device (acc_device_t dev)
> {
> + if (!acc_known_device_type (dev))
> + unknown_device_type_error(dev);
> +
> return __builtin_acc_on_device (dev);
> }
Please drop this last one; maybe mention this in the function comment.
This function is meant to just forward to '__builtin_acc_on_device'. Any
'acc_known_device_type' checking should thus be done as part of the
builtin expansion -- if that's feasible at all. This will need further
thought, can be addressed later.
> @@ -836,6 +877,9 @@ goacc_runtime_initialize (void)
> attribute_hidden void
> goacc_save_and_set_bind (acc_device_t d)
> {
> + if (!acc_known_device_type (d))
> + unknown_device_type_error (d);
> +
> struct goacc_thread *thr = goacc_thread ();
>
> assert (!thr->saved_bound_dev);
This is an internal-only function, guaranteed to always be called with a
valid 'acc_device_t', so if anything at all, this should 'assert', or
just drop this one.
Grüße
Thomas
More information about the Gcc-patches
mailing list