Skip to content

Commit

Permalink
msg: Return a handle instead of kernel pointer in msgRecv
Browse files Browse the repository at this point in the history
Breaking API change!

Add idtree from libphoenix, some MISRA improvements

JIRA: RTOS-606
  • Loading branch information
agkaminski committed Sep 15, 2023
1 parent a4f4770 commit 841daa5
Show file tree
Hide file tree
Showing 14 changed files with 503 additions and 124 deletions.
3 changes: 3 additions & 0 deletions include/msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#ifndef _PHOENIX_MSG_H_
#define _PHOENIX_MSG_H_

/* Return id, allocated in msgReceive, used in msgRespond */
typedef unsigned int msg_rid_t;

/*
* Message types
*/
Expand Down
2 changes: 1 addition & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
# Author: Pawel Pisarczyk
#

OBJS += $(addprefix $(PREFIX_O)lib/, assert.o printf.o bsearch.o rand.o strtoul.o rb.o list.o cbuffer.o strutil.o)
OBJS += $(addprefix $(PREFIX_O)lib/, assert.o printf.o bsearch.o rand.o strtoul.o rb.o list.o cbuffer.o strutil.o idtree.o)

162 changes: 162 additions & 0 deletions lib/idtree.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* id allocating tree
*
* Copyright 2018, 2023 Phoenix Systems
* Author: Jan Sikorski, Aleksander Kaminski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include "lib.h"


static int lib_idtreeCmp(rbnode_t *n1, rbnode_t *n2)
{
idnode_t *i1 = lib_treeof(idnode_t, linkage, n1);
idnode_t *i2 = lib_treeof(idnode_t, linkage, n2);

if (i1->id > i2->id) {
return 1;
}
else if (i2->id > i1->id) {
return -1;
}
else {
return 0;
}
}


static int lib_idtreeGapcmp(rbnode_t *n1, rbnode_t *n2)
{
idnode_t *r1 = lib_treeof(idnode_t, linkage, n1);
idnode_t *r2 = lib_treeof(idnode_t, linkage, n2);
int ret;

if ((r1->lmaxgap > 0) && (r1->rmaxgap > 0)) {
if (r2->id > r1->id) {
ret = -1;
}
else {
ret = 1;
}
}
else if (r1->lmaxgap > 0) {
ret = 1;
}
else if (r1->rmaxgap > 0) {
ret = -1;
}
else {
ret = 0;
}

return ret;
}


static void lib_idtreeAugment(rbnode_t *node)
{
rbnode_t *it;
idnode_t *n = lib_treeof(idnode_t, linkage, node);
idnode_t *p = n, *r, *l;

if (node->left == NULL) {
for (it = node; it->parent != NULL; it = it->parent) {
p = lib_treeof(idnode_t, linkage, it->parent);
if (it->parent->right == it) {
break;
}
}

n->lmaxgap = (n->id <= p->id) ? n->id : (n->id - p->id - 1);
}
else {
l = lib_treeof(idnode_t, linkage, node->left);
n->lmaxgap = max(l->lmaxgap, l->rmaxgap);
}

if (node->right == NULL) {
for (it = node; it->parent != NULL; it = it->parent) {
p = lib_treeof(idnode_t, linkage, it->parent);
if (it->parent->left == it) {
break;
}
}

n->rmaxgap = (n->id >= p->id) ? ((unsigned)-1 - n->id - 1) : (p->id - n->id - 1);
}
else {
r = lib_treeof(idnode_t, linkage, node->right);
n->rmaxgap = max(r->lmaxgap, r->rmaxgap);
}

for (it = node; it->parent != NULL; it = it->parent) {
n = lib_treeof(idnode_t, linkage, it);
p = lib_treeof(idnode_t, linkage, it->parent);

if (it->parent->left == it) {
p->lmaxgap = max(n->lmaxgap, n->rmaxgap);
}
else {
p->rmaxgap = max(n->lmaxgap, n->rmaxgap);
}
}
}


idnode_t *lib_idtreeFind(idtree_t *tree, int id)
{
idnode_t n;
n.id = id;
return lib_treeof(idnode_t, linkage, lib_rbFind(tree, &n.linkage));
}


void lib_idtreeRemove(idtree_t *tree, idnode_t *node)
{
lib_rbRemove(tree, &node->linkage);
}


int lib_idtreeId(idnode_t *node)
{
return node->id;
}


int lib_idtreeAlloc(idtree_t *tree, idnode_t *n)
{
idnode_t *f;

n->id = 0;
if (tree->root != NULL) {
f = lib_treeof(idnode_t, linkage, lib_rbFindEx(tree->root, &n->linkage, lib_idtreeGapcmp));

if (f != NULL) {
if (f->lmaxgap > 0) {
n->id = f->id - 1;
}
else {
n->id = f->id + 1;
}
}
else {
return -1;
}
}

lib_rbInsert(tree, &n->linkage);
return n->id;
}

void lib_idtreeInit(idtree_t *tree)
{
lib_rbInit(tree, lib_idtreeCmp, lib_idtreeAugment);
}
53 changes: 53 additions & 0 deletions lib/idtree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* id allocating tree
*
* Copyright 2018, 2023 Phoenix Systems
* Author: Jan Sikorski, Aleksander Kaminski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#ifndef _PHOENIX_IDTREE_H_
#define _PHOENIX_IDTREE_H_

#include "rb.h"


typedef rbtree_t idtree_t;


typedef struct {
rbnode_t linkage;
unsigned int lmaxgap, rmaxgap;
unsigned int id;
} idnode_t;


#define lib_idtreeof(type, node_field, node) ({ \
long _off = (long)&(((type *)0)->node_field); \
idnode_t *tmpnode = (node); \
(type *)((tmpnode == NULL) ? NULL : ((void *)tmpnode - _off)); \
})


idnode_t *lib_idtreeFind(idtree_t *tree, int id);


void lib_idtreeRemove(idtree_t *tree, idnode_t *node);


int lib_idtreeId(idnode_t *node);


int lib_idtreeAlloc(idtree_t *tree, idnode_t *n);


void lib_idtreeInit(idtree_t *tree);

#endif
1 change: 1 addition & 0 deletions lib/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "list.h"
#include "assert.h"
#include "strutil.h"
#include "idtree.h"


#define lib_atomicIncrement(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_RELAXED)
Expand Down
10 changes: 4 additions & 6 deletions lib/rb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
#ifndef _LIB_RB_H_
#define _LIB_RB_H_

//#include "../hal/hal.h"


#define lib_treeof(type, node_field, node) ({ \
long _off = (long) &(((type *) 0)->node_field); \
rbnode_t *tmpnode = (node); \
(type *) ((tmpnode == NULL) ? NULL : ((void *) tmpnode - _off)); \
#define lib_treeof(type, node_field, node) ({ \
long _off = (long)&(((type *)0)->node_field); \
rbnode_t *tmpnode = (node); \
(type *)((tmpnode == NULL) ? NULL : ((void *)tmpnode - _off)); \
})


Expand Down
68 changes: 54 additions & 14 deletions proc/msg-nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ int proc_send(u32 port, msg_t *msg)
thread_t *sender;
spinlock_ctx_t sc;

if ((p = proc_portGet(port)) == NULL)
p = proc_portGet(port);
if (p == NULL) {
return -EINVAL;
}

sender = proc_current();

Expand All @@ -55,34 +57,54 @@ int proc_send(u32 port, msg_t *msg)
}
else {
LIST_ADD(&p->kmessages, &kmsg);

proc_threadWakeup(&p->threads);

while (kmsg.state != msg_responded && kmsg.state != msg_rejected)
err = proc_threadWait(&kmsg.threads, &p->spinlock, 0, &sc);
while ((kmsg.state != msg_responded) && (kmsg.state != msg_rejected)) {
err = proc_threadWaitInterruptible(&kmsg.threads, &p->spinlock, 0, &sc);

if ((err != EOK) && (kmsg.state == msg_waiting)) {
LIST_REMOVE(&p->kmessages, &kmsg);
break;
}
}

switch (kmsg.state) {
case msg_responded:
err = EOK; /* Don't report EINTR if we got the response already */
break;
case msg_rejected:
err = -EINVAL;
break;
default:
break;
}
}

hal_spinlockClear(&p->spinlock, &sc);

port_put(p, 0);

return kmsg.state == msg_rejected ? -EINVAL : err;
return err;
}


int proc_recv(u32 port, msg_t *msg, unsigned long int *rid)
int proc_recv(u32 port, msg_t *msg, msg_rid_t *rid)
{
port_t *p;
kmsg_t *kmsg;
spinlock_ctx_t sc;
int err = 0;

if ((p = proc_portGet(port)) == NULL)
p = proc_portGet(port);
if (p == NULL) {
return -EINVAL;
}

hal_spinlockSet(&p->spinlock, &sc);

while (p->kmessages == NULL && !p->closed)
proc_threadWait(&p->threads, &p->spinlock, 0, &sc);
while ((p->kmessages == NULL) && (p->closed == 0) && (err != -EINTR)) {
err = proc_threadWaitInterruptible(&p->threads, &p->spinlock, 0, &sc);
}

kmsg = p->kmessages;

Expand All @@ -99,29 +121,47 @@ int proc_recv(u32 port, msg_t *msg, unsigned long int *rid)
return -EINVAL;
}

if (proc_portRidAlloc(p, kmsg) < 0) {
hal_spinlockSet(&p->spinlock, &sc);
kmsg->state = msg_rejected;
proc_threadWakeup(&kmsg->threads);
hal_spinlockClear(&p->spinlock, &sc);

port_put(p, 0);

return -ENOMEM;
}

kmsg->state = msg_received;
LIST_REMOVE(&p->kmessages, kmsg);
hal_spinlockClear(&p->spinlock, &sc);

/* (MOD) */
(*rid) = (unsigned long)(kmsg);
*rid = lib_idtreeId(&kmsg->idlinkage);

hal_memcpy(msg, kmsg->msg, sizeof(*msg));

port_put(p, 0);

return EOK;
}


int proc_respond(u32 port, msg_t *msg, unsigned long int rid)
int proc_respond(u32 port, msg_t *msg, msg_rid_t rid)
{
port_t *p;
size_t s = 0;
kmsg_t *kmsg = (kmsg_t *)(unsigned long)rid;
kmsg_t *kmsg;
spinlock_ctx_t sc;

if ((p = proc_portGet(port)) == NULL)
p = proc_portGet(port);
if (p == NULL) {
return -EINVAL;
}

kmsg = proc_portRidGet(p, rid);
if (kmsg == NULL) {
return -ENOENT;
}

hal_memcpy(kmsg->msg->o.raw, msg->o.raw, sizeof(msg->o.raw));

Expand Down
Loading

0 comments on commit 841daa5

Please sign in to comment.