/*
* Copyright (c) 2021 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#ifndef _IOKIT_UIOWORKGROUP_H
#define _IOKIT_UIOWORKGROUP_H
#include <DriverKit/OSObject.iig>
#include <DriverKit/IOUserClient.iig>
enum {
kIOWorkGroupMaxNameLength = 64,
};
/*!
* @class IOWorkGroup
*
* @abstract
* Workgroups allow multiple threads to coordinate activities for realtime operations.
*
* @discussion
*
* Applications that open user clients to a DriverKit driver can send a workgroup to use in the driver.
*
* The application will have to first create an workgroup object. The application then should copy the
* workgroup port with os_workgroup_copy_port(). To send the workgroup port to the driver, use:
*
* const char * name = "Work Group Name"; // This must match the name the driver used in IOWorkGroup::Create().
* kern_return_t ret = IOConnectTrap3(connect, // user client connection (io_connect_t)
* 1, // specifies event link configuration trap
* (uintptr_t)name,
* (uintptr_t)strlen(name),
* (uintptr_t)wgPort // port from os_workgroup_copy_port
* );
*
* Once the workgroup port has been sent to the driver, the driver should be notified with a user-defined external method
* or other existing signaling mechanism.
*/
class NATIVE KERNEL IOWorkGroup : public OSObject
{
public:
virtual bool
init() override;
virtual void
free() override;
/*!
* @brief Create an IOWorkGroup object. This object is not functional until a workgroup port has been set.
* @param name Name of the workgroup
* @param userClient Userclient to create the workgroup in. The DriverKit runtime will retain the userclient, and will
* release it in Invalidate() or when the IOWorkGroup is freed.
* @param workgroup Created IOWorkGroup with +1 retain count to be released by the caller.
* @return kIOReturnSuccess on success. See IOReturn.h for error codes.
*/
static kern_return_t
Create(OSString * name, IOUserClient * userClient, IOWorkGroup ** workgroup) LOCAL;
#if DRIVERKIT_PRIVATE
/*!
* @brief Set the port for this workgroup. This should not be called directly.
* @param port Workgroup port
* @return kIOReturnSuccess on success. See IOReturn.h for error codes.
*/
virtual kern_return_t
SetWorkGroupPort(mach_port_t port PORTCOPYSEND) LOCAL;
#endif /* DRIVERKIT_PRIVATE */
/*!
* @brief Get the size of the workgroup token.
* @discussion Join() and Leave() require the caller to pass a token. This token should be allocated by the caller, and freed when
* no longer needed. Use this method to determine how much memory to allocate for the token.
* @return Workgroup token size
*/
size_t
GetTokenSize() LOCALONLY;
/*!
* @brief Join the workgroup.
* @discussion Before calling this method, the caller must allocate a token. This token must be passed to this method. When leaving
* a workgroup with Leave(), use the same token that was passed to Join().
* @param token The workgroup token.
* @return kIOReturnSuccess on success. See IOReturn.h for error codes.
*/
kern_return_t
Join(void * token) LOCALONLY;
/*!
* @brief Leave the workgroup.
* @discussion The workgroup must have been joined with Join(). Use the same token in Join() for this method.
* @param token The workgroup token.
* @return kIOReturnSuccess on success. See IOReturn.h for error codes.
*/
kern_return_t
Leave(void * token) LOCALONLY;
/*!
* @brief Invalidate the IOWorkGroup.
* @discussion This releases the kernel reference to the IOWorkGroup, allowing the name to be used for a different
* IOWorkGroup. This method should be called after the client has configured the eventlink with the IOConnectTrap
* call. After invalidation, the IOWorkGroup can no longer be configured through the IOConnectTrap call. No other
* functionality is affected.
* @return kIOReturnSuccess on success. See IOReturn.h for error codes.
*/
kern_return_t
Invalidate() LOCALONLY;
#if DRIVERKIT_PRIVATE
virtual kern_return_t
InvalidateKernel(IOUserClient * client);
#endif /* DRIVERKIT_PRIVATE */
};
#endif /* ! _IOKIT_UIOWORKGROUP_H */