Const fn in generic structure

This is a structure for bare metal symmetric multi-programming where each thread operates exclusively on a different section of the output.

pub struct SharedMatrix<'a> {
    matrix: UnsafeCell<Matrix>,
    sections: UnsafeCell<Option<[Option<MatrixSection<'a>>; N_HARTS]>>,
    initializing: AtomicBool,
    initialized: AtomicBool,
    section_available: [AtomicBool; N_HARTS],
    computation_completed: AtomicUsize,
}

impl<'a> SharedMatrix<'a> {
    pub const fn new() -> Self {
        SharedMatrix {
            matrix: UnsafeCell::new(Matrix::zeroes()),
            sections: UnsafeCell::new(None),
            initializing: AtomicBool::new(false),
            initialized: AtomicBool::new(false),
            section_available: [
                AtomicBool::new(true),
                AtomicBool::new(true),
                AtomicBool::new(true),
                AtomicBool::new(true),
            ],
            computation_completed: AtomicUsize::new(0),
        }
    }
    ...
}

I'd like to make the shared structure generic over the inner type, so that I can use it to share other structures than a matrix (SharedMatrix contains some methods to allow to get mutable references to part of it and keep track of if a section is available etc.). However, when I write the generic code I run into a problem:

pub trait SectionsMut {
    type Section;
    fn sections_mut(&mut self) -> [Option<Self::Section>; N_HARTS];
}

pub struct SharedStructure<Inner: SectionsMut<Section = InnerSection>, InnerSection> {
    data: UnsafeCell<Inner>,
    sections: UnsafeCell<Option<[Option<InnerSection>; N_HARTS]>>,
    initializing: AtomicBool,
    initialized: AtomicBool,
    section_available: [AtomicBool; N_HARTS],
    computation_completed: AtomicUsize,
}

impl<Inner: SectionsMut<Section = InnerSection>, InnerSection>
    SharedStructure<Inner, InnerSection>
{
    pub const fn new() -> Self {
        SharedStructure {
            data: UnsafeCell::new(Inner::zeroes()),
            sections: UnsafeCell::new(None),
            initializing: AtomicBool::new(false),
            initialized: AtomicBool::new(false),
            section_available: [
                AtomicBool::new(true),
                AtomicBool::new(true),
                AtomicBool::new(true),
                AtomicBool::new(true),
            ],
            computation_completed: AtomicUsize::new(0),
        }
    }
    ...
}

The new method has to be const because the structure needs to be initialized in a static context to be shared amongst the threads, so Inner::zeroes() has to be const. These are the solutions I came up with:

  1. Have a pub trait ConstInit {} that contains const fn zeroes() -> Self and add it as a trait bound on Inner, however a trait cannot have a const member
  2. Pass a const fn to the new() method on SharedStructure to handle the initialization, which does not compile as well

What would you advise as a possible alternative?

The simplest solution is probably just to require the caller to pass in the value you need to the function.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.