summaryrefslogtreecommitdiff
path: root/ipc
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-10-01 15:39:49 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-10-01 15:59:22 +0200
commite64697e4abda6c7ef512f4a2948c0d777d668be9 (patch)
treec9307d06b177dbf6da5e8acb92eeab4bd86118ed /ipc
parent922e514ad93bf21985659ad10a96019a20ad4c10 (diff)
Add and use ikm_cache_alloc/free/_try
Diffstat (limited to 'ipc')
-rw-r--r--ipc/ipc_kmsg.c19
-rw-r--r--ipc/ipc_kmsg.h40
-rw-r--r--ipc/mach_msg.c15
3 files changed, 52 insertions, 22 deletions
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index d31c3ee9..bd1b30da 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -494,16 +494,9 @@ ipc_kmsg_get(
return MACH_SEND_MSG_TOO_SMALL;
if (size <= IKM_SAVED_MSG_SIZE) {
- kmsg = ikm_cache();
- if (kmsg != IKM_NULL) {
- ikm_cache() = IKM_NULL;
- ikm_check_initialized(kmsg, IKM_SAVED_KMSG_SIZE);
- } else {
- kmsg = ikm_alloc(IKM_SAVED_MSG_SIZE);
- if (kmsg == IKM_NULL)
- return MACH_SEND_NO_BUFFER;
- ikm_init(kmsg, IKM_SAVED_MSG_SIZE);
- }
+ kmsg = ikm_cache_alloc();
+ if (kmsg == IKM_NULL)
+ return MACH_SEND_NO_BUFFER;
} else {
kmsg = ikm_alloc(size);
if (kmsg == IKM_NULL)
@@ -585,11 +578,7 @@ ipc_kmsg_put(
else
mr = MACH_MSG_SUCCESS;
- if ((kmsg->ikm_size == IKM_SAVED_KMSG_SIZE) &&
- (ikm_cache() == IKM_NULL))
- ikm_cache() = kmsg;
- else
- ikm_free(kmsg);
+ ikm_cache_free(kmsg);
return mr;
}
diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h
index b1eb06c7..45e174b7 100644
--- a/ipc/ipc_kmsg.h
+++ b/ipc/ipc_kmsg.h
@@ -102,6 +102,46 @@ extern ipc_kmsg_t ipc_kmsg_cache[NCPUS];
#define ikm_cache() ipc_kmsg_cache[cpu_number()]
+#define ikm_cache_alloc_try() \
+MACRO_BEGIN \
+ ipc_kmsg_t __kmsg = ikm_cache(); \
+ if (__kmsg != IKM_NULL) { \
+ ikm_cache() = IKM_NULL; \
+ ikm_check_initialized(__kmsg, IKM_SAVED_KMSG_SIZE); \
+ } \
+ __kmsg; \
+MACRO_END
+
+#define ikm_cache_alloc() \
+MACRO_BEGIN \
+ ipc_kmsg_t __kmsg = ikm_cache_alloc_try(); \
+ if (!__kmsg) { \
+ __kmsg = ikm_alloc(IKM_SAVED_MSG_SIZE); \
+ if (__kmsg != IKM_NULL) \
+ ikm_init(__kmsg, IKM_SAVED_MSG_SIZE); \
+ } \
+ __kmsg; \
+MACRO_END
+
+#define ikm_cache_free_try(kmsg) \
+MACRO_BEGIN \
+ int __success = 0; \
+ if (ikm_cache() == IKM_NULL) { \
+ ikm_cache() = (kmsg); \
+ __success = 1; \
+ } \
+ __success; \
+MACRO_END
+
+#define ikm_cache_free(kmsg) \
+MACRO_BEGIN \
+ if (((kmsg)->ikm_size == IKM_SAVED_KMSG_SIZE) && \
+ (ikm_cache() == IKM_NULL)) \
+ ikm_cache() = (kmsg); \
+ else \
+ ikm_free(kmsg); \
+MACRO_END
+
/*
* The size of the kernel message buffers that will be cached.
* IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c
index 46218bb6..482c85a5 100644
--- a/ipc/mach_msg.c
+++ b/ipc/mach_msg.c
@@ -452,12 +452,12 @@ mach_msg_trap(
if ((send_size > IKM_SAVED_MSG_SIZE) ||
(send_size < sizeof(mach_msg_user_header_t)) ||
- (send_size & 3) ||
- ((kmsg = ikm_cache()) == IKM_NULL))
+ (send_size & 3))
goto slow_get;
- ikm_cache() = IKM_NULL;
- ikm_check_initialized(kmsg, IKM_SAVED_KMSG_SIZE);
+ kmsg = ikm_cache_alloc_try();
+ if (kmsg == IKM_NULL)
+ goto slow_get;
if (copyinmsg(msg, &kmsg->ikm_header,
send_size)) {
@@ -1176,11 +1176,12 @@ mach_msg_trap(
if ((kmsg->ikm_size != IKM_SAVED_KMSG_SIZE) ||
copyoutmsg(&kmsg->ikm_header, msg,
- reply_size) ||
- (ikm_cache() != IKM_NULL))
+ reply_size))
+ goto slow_put;
+
+ if (!ikm_cache_free_try(kmsg))
goto slow_put;
- ikm_cache() = kmsg;
thread_syscall_return(MACH_MSG_SUCCESS);
/*NOTREACHED*/
return MACH_MSG_SUCCESS; /* help for the compiler */