Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
spbro
OpenXG-RAN
Commits
872cfc03
Commit
872cfc03
authored
Apr 12, 2020
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement Static Slicing
parent
9956b960
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
707 additions
and
0 deletions
+707
-0
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+1
-0
openair2/LAYER2/MAC/slicing/slicing.c
openair2/LAYER2/MAC/slicing/slicing.c
+586
-0
openair2/LAYER2/MAC/slicing/slicing.h
openair2/LAYER2/MAC/slicing/slicing.h
+74
-0
openair2/LAYER2/MAC/slicing/slicing_internal.h
openair2/LAYER2/MAC/slicing/slicing_internal.h
+46
-0
No files found.
cmake_targets/CMakeLists.txt
View file @
872cfc03
...
...
@@ -1830,6 +1830,7 @@ set (MAC_SRC
${
MAC_DIR
}
/eNB_scheduler_fairRR.c
${
MAC_DIR
}
/eNB_scheduler_phytest.c
${
MAC_DIR
}
/pre_processor.c
${
MAC_DIR
}
/slicing/slicing.c
${
MAC_DIR
}
/config.c
${
MAC_DIR
}
/config_ue.c
)
...
...
openair2/LAYER2/MAC/slicing/slicing.c
0 → 100644
View file @
872cfc03
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*!
* \file slicing.c
* \brief Generic slicing helper functions and Static Slicing Implementation
* \author Robert Schmidt
* \date 2020
* \email robert.schmidt@eurecom.fr
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <dlfcn.h>
#include "assertions.h"
#include "common/utils/LOG/log.h"
#include "slicing.h"
#include "slicing_internal.h"
#include "common/ran_context.h"
extern
RAN_CONTEXT_t
RC
;
#define RET_FAIL(ret, x...) do { LOG_E(MAC, x); return ret; } while (0)
int
slicing_get_UE_slice_idx
(
slice_info_t
*
si
,
int
UE_id
)
{
return
si
->
UE_assoc_slice
[
UE_id
];
}
void
slicing_add_UE
(
slice_info_t
*
si
,
int
UE_id
)
{
add_ue_list
(
&
si
->
s
[
0
]
->
UEs
,
UE_id
);
si
->
UE_assoc_slice
[
UE_id
]
=
0
;
}
void
_remove_UE
(
slice_t
**
s
,
uint8_t
*
assoc
,
int
UE_id
)
{
const
uint8_t
i
=
assoc
[
UE_id
];
DevAssert
(
remove_ue_list
(
&
s
[
i
]
->
UEs
,
UE_id
));
assoc
[
UE_id
]
=
-
1
;
}
void
slicing_remove_UE
(
slice_info_t
*
si
,
int
UE_id
)
{
_remove_UE
(
si
->
s
,
si
->
UE_assoc_slice
,
UE_id
);
}
void
_move_UE
(
slice_t
**
s
,
uint8_t
*
assoc
,
int
UE_id
,
int
to
)
{
const
uint8_t
i
=
assoc
[
UE_id
];
const
int
ri
=
remove_ue_list
(
&
s
[
i
]
->
UEs
,
UE_id
);
if
(
!
ri
)
LOG_W
(
MAC
,
"did not find UE %d in DL slice index %d
\n
"
,
UE_id
,
i
);
add_ue_list
(
&
s
[
to
]
->
UEs
,
UE_id
);
assoc
[
UE_id
]
=
to
;
}
void
slicing_move_UE
(
slice_info_t
*
si
,
int
UE_id
,
int
idx
)
{
DevAssert
(
idx
>=
-
1
&&
idx
<
si
->
num
);
if
(
idx
>=
0
)
_move_UE
(
si
->
s
,
si
->
UE_assoc_slice
,
UE_id
,
idx
);
}
int
_exists_slice
(
uint8_t
n
,
slice_t
**
s
,
int
id
)
{
for
(
int
i
=
0
;
i
<
n
;
++
i
)
if
(
s
[
i
]
->
id
==
id
)
return
i
;
return
-
1
;
}
slice_t
*
_add_slice
(
uint8_t
*
n
,
slice_t
**
s
)
{
s
[
*
n
]
=
calloc
(
1
,
sizeof
(
slice_t
));
if
(
!
s
[
*
n
])
return
NULL
;
init_ue_list
(
&
s
[
*
n
]
->
UEs
);
*
n
+=
1
;
return
s
[
*
n
-
1
];
}
slice_t
*
_remove_slice
(
uint8_t
*
n
,
slice_t
**
s
,
uint8_t
*
assoc
,
int
idx
)
{
if
(
idx
>=
*
n
)
return
NULL
;
slice_t
*
sr
=
s
[
idx
];
while
(
sr
->
UEs
.
head
>=
0
)
_move_UE
(
s
,
assoc
,
sr
->
UEs
.
head
,
0
);
for
(
int
i
=
idx
+
1
;
i
<
*
n
;
++
i
)
s
[
i
-
1
]
=
s
[
i
];
*
n
-=
1
;
s
[
*
n
]
=
NULL
;
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_ENB
;
++
i
)
if
(
assoc
[
i
]
>
idx
)
assoc
[
i
]
-=
1
;
if
(
sr
->
label
)
free
(
sr
->
label
);
return
sr
;
}
/************************ Static Slicing Implementation ************************/
int
addmod_static_slice_dl
(
slice_info_t
*
si
,
int
id
,
char
*
label
,
void
*
algo
,
void
*
slice_params_dl
)
{
static_slice_param_t
*
dl
=
slice_params_dl
;
if
(
dl
&&
dl
->
posLow
>
dl
->
posHigh
)
RET_FAIL
(
-
1
,
"%s(): slice id %d posLow > posHigh
\n
"
,
__func__
,
id
);
uint8_t
rbgMap
[
25
]
=
{
0
};
int
index
=
_exists_slice
(
si
->
num
,
si
->
s
,
id
);
if
(
index
>=
0
)
{
for
(
int
s
=
0
;
s
<
si
->
num
;
++
s
)
{
static_slice_param_t
*
sd
=
dl
&&
si
->
s
[
s
]
->
id
==
id
?
dl
:
si
->
s
[
s
]
->
algo_data
;
for
(
int
i
=
sd
->
posLow
;
i
<=
sd
->
posHigh
;
++
i
)
{
if
(
rbgMap
[
i
])
RET_FAIL
(
-
33
,
"%s(): overlap of slices detected at RBG %d
\n
"
,
__func__
,
i
);
rbgMap
[
i
]
=
1
;
}
}
/* no problem, can allocate */
slice_t
*
s
=
si
->
s
[
index
];
if
(
label
)
{
if
(
s
->
label
)
free
(
s
->
label
);
s
->
label
=
label
;
}
if
(
algo
)
{
s
->
dl_algo
.
unset
(
&
s
->
dl_algo
.
data
);
s
->
dl_algo
=
*
(
default_sched_dl_algo_t
*
)
algo
;
if
(
!
s
->
dl_algo
.
data
)
s
->
dl_algo
.
data
=
s
->
dl_algo
.
setup
();
}
if
(
dl
)
{
free
(
s
->
algo_data
);
s
->
algo_data
=
dl
;
}
return
index
;
}
if
(
!
dl
)
RET_FAIL
(
-
100
,
"%s(): no parameters for new slice %d, aborting
\n
"
,
__func__
,
id
);
if
(
si
->
num
>=
MAX_STATIC_SLICES
)
RET_FAIL
(
-
2
,
"%s(): cannot have more than %d slices
\n
"
,
__func__
,
MAX_STATIC_SLICES
);
for
(
int
s
=
0
;
s
<
si
->
num
;
++
s
)
{
static_slice_param_t
*
sd
=
si
->
s
[
s
]
->
algo_data
;
for
(
int
i
=
sd
->
posLow
;
i
<=
sd
->
posHigh
;
++
i
)
rbgMap
[
i
]
=
1
;
}
for
(
int
i
=
dl
->
posLow
;
i
<=
dl
->
posHigh
;
++
i
)
if
(
rbgMap
[
i
])
RET_FAIL
(
-
3
,
"%s(): overlap of slices detected at RBG %d
\n
"
,
__func__
,
i
);
if
(
!
algo
)
RET_FAIL
(
-
14
,
"%s(): no scheduler algorithm provided
\n
"
,
__func__
);
slice_t
*
ns
=
_add_slice
(
&
si
->
num
,
si
->
s
);
if
(
!
ns
)
RET_FAIL
(
-
4
,
"%s(): could not create new slice
\n
"
,
__func__
);
ns
->
id
=
id
;
ns
->
label
=
label
;
ns
->
dl_algo
=
*
(
default_sched_dl_algo_t
*
)
algo
;
if
(
!
ns
->
dl_algo
.
data
)
ns
->
dl_algo
.
data
=
ns
->
dl_algo
.
setup
();
ns
->
algo_data
=
dl
;
return
si
->
num
-
1
;
}
int
addmod_static_slice_ul
(
slice_info_t
*
si
,
int
id
,
char
*
label
,
void
*
algo
,
void
*
slice_params_ul
)
{
static_slice_param_t
*
ul
=
slice_params_ul
;
/* Minimum 3RBs, because LTE stack requires this */
if
(
ul
&&
ul
->
posLow
+
2
>
ul
->
posHigh
)
RET_FAIL
(
-
1
,
"%s(): slice id %d posLow + 2 > posHigh
\n
"
,
__func__
,
id
);
uint8_t
rbMap
[
110
]
=
{
0
};
int
index
=
_exists_slice
(
si
->
num
,
si
->
s
,
id
);
if
(
index
>=
0
)
{
for
(
int
s
=
0
;
s
<
si
->
num
;
++
s
)
{
static_slice_param_t
*
su
=
ul
&&
si
->
s
[
s
]
->
id
==
id
&&
ul
?
ul
:
si
->
s
[
s
]
->
algo_data
;
for
(
int
i
=
su
->
posLow
;
i
<=
su
->
posHigh
;
++
i
)
{
if
(
rbMap
[
i
])
RET_FAIL
(
-
33
,
"%s(): overlap of slices detected at RBG %d
\n
"
,
__func__
,
i
);
rbMap
[
i
]
=
1
;
}
}
/* no problem, can allocate */
slice_t
*
s
=
si
->
s
[
index
];
if
(
algo
)
{
s
->
ul_algo
.
unset
(
&
s
->
ul_algo
.
data
);
s
->
ul_algo
=
*
(
default_sched_ul_algo_t
*
)
algo
;
if
(
!
s
->
ul_algo
.
data
)
s
->
ul_algo
.
data
=
s
->
ul_algo
.
setup
();
}
if
(
label
)
{
if
(
s
->
label
)
free
(
s
->
label
);
s
->
label
=
label
;
}
if
(
ul
)
{
free
(
s
->
algo_data
);
s
->
algo_data
=
ul
;
}
return
index
;
}
if
(
!
ul
)
RET_FAIL
(
-
100
,
"%s(): no parameters for new slice %d, aborting
\n
"
,
__func__
,
id
);
if
(
si
->
num
>=
MAX_STATIC_SLICES
)
RET_FAIL
(
-
2
,
"%s(): cannot have more than %d slices
\n
"
,
__func__
,
MAX_STATIC_SLICES
);
for
(
int
s
=
0
;
s
<
si
->
num
;
++
s
)
{
static_slice_param_t
*
sd
=
si
->
s
[
s
]
->
algo_data
;
for
(
int
i
=
sd
->
posLow
;
i
<=
sd
->
posHigh
;
++
i
)
rbMap
[
i
]
=
1
;
}
for
(
int
i
=
ul
->
posLow
;
i
<=
ul
->
posHigh
;
++
i
)
if
(
rbMap
[
i
])
RET_FAIL
(
-
3
,
"%s(): overlap of slices detected at RBG %d
\n
"
,
__func__
,
i
);
if
(
!
algo
)
RET_FAIL
(
-
14
,
"%s(): no scheduler algorithm provided
\n
"
,
__func__
);
slice_t
*
ns
=
_add_slice
(
&
si
->
num
,
si
->
s
);
if
(
!
ns
)
RET_FAIL
(
-
4
,
"%s(): could not create new slice
\n
"
,
__func__
);
ns
->
id
=
id
;
ns
->
label
=
label
;
ns
->
ul_algo
=
*
(
default_sched_ul_algo_t
*
)
algo
;
if
(
!
ns
->
ul_algo
.
data
)
ns
->
ul_algo
.
data
=
ns
->
ul_algo
.
setup
();
ns
->
algo_data
=
ul
;
return
si
->
num
-
1
;
}
int
remove_static_slice
(
slice_info_t
*
si
,
uint8_t
slice_idx
)
{
if
(
slice_idx
==
0
)
return
0
;
slice_t
*
sr
=
_remove_slice
(
&
si
->
num
,
si
->
s
,
si
->
UE_assoc_slice
,
slice_idx
);
if
(
!
sr
)
return
0
;
free
(
sr
->
algo_data
);
free
(
sr
);
return
1
;
}
void
static_dl
(
module_id_t
mod_id
,
int
CC_id
,
frame_t
frame
,
sub_frame_t
subframe
)
{
UE_info_t
*
UE_info
=
&
RC
.
mac
[
mod_id
]
->
UE_info
;
store_dlsch_buffer
(
mod_id
,
CC_id
,
frame
,
subframe
);
for
(
int
UE_id
=
UE_info
->
list
.
head
;
UE_id
>=
0
;
UE_id
=
UE_info
->
list
.
next
[
UE_id
])
{
UE_sched_ctrl_t
*
ue_sched_ctrl
=
&
UE_info
->
UE_sched_ctrl
[
UE_id
];
/* initialize per-UE scheduling information */
ue_sched_ctrl
->
pre_nb_available_rbs
[
CC_id
]
=
0
;
ue_sched_ctrl
->
dl_pow_off
[
CC_id
]
=
2
;
memset
(
ue_sched_ctrl
->
rballoc_sub_UE
[
CC_id
],
0
,
sizeof
(
ue_sched_ctrl
->
rballoc_sub_UE
[
CC_id
]));
ue_sched_ctrl
->
pre_dci_dl_pdu_idx
=
-
1
;
}
const
int
N_RBG
=
to_rbg
(
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
].
mib
->
message
.
dl_Bandwidth
);
const
int
RBGsize
=
get_min_rb_unit
(
mod_id
,
CC_id
);
uint8_t
*
vrb_map
=
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
].
vrb_map
;
uint8_t
rbgalloc_mask
[
N_RBG_MAX
];
for
(
int
i
=
0
;
i
<
N_RBG
;
i
++
)
{
// calculate mask: init to one + "AND" with vrb_map:
// if any RB in vrb_map is blocked (1), the current RBG will be 0
rbgalloc_mask
[
i
]
=
1
;
for
(
int
j
=
0
;
j
<
RBGsize
;
j
++
)
rbgalloc_mask
[
i
]
&=
!
vrb_map
[
RBGsize
*
i
+
j
];
}
slice_info_t
*
s
=
RC
.
mac
[
mod_id
]
->
pre_processor_dl
.
slices
;
int
max_num_ue
;
switch
(
s
->
num
)
{
case
1
:
max_num_ue
=
4
;
break
;
case
2
:
max_num_ue
=
2
;
break
;
default:
max_num_ue
=
1
;
break
;
}
for
(
int
i
=
0
;
i
<
s
->
num
;
++
i
)
{
if
(
s
->
s
[
i
]
->
UEs
.
head
<
0
)
continue
;
uint8_t
rbgalloc_slice_mask
[
N_RBG_MAX
];
memset
(
rbgalloc_slice_mask
,
0
,
sizeof
(
rbgalloc_slice_mask
));
static_slice_param_t
*
p
=
s
->
s
[
i
]
->
algo_data
;
int
n_rbg_sched
=
0
;
for
(
int
rbg
=
p
->
posLow
;
rbg
<=
p
->
posHigh
&&
rbg
<=
N_RBG
;
++
rbg
)
{
rbgalloc_slice_mask
[
rbg
]
=
rbgalloc_mask
[
rbg
];
n_rbg_sched
+=
rbgalloc_mask
[
rbg
];
}
s
->
s
[
i
]
->
dl_algo
.
run
(
mod_id
,
CC_id
,
frame
,
subframe
,
&
s
->
s
[
i
]
->
UEs
,
max_num_ue
,
// max_num_ue
n_rbg_sched
,
rbgalloc_slice_mask
,
s
->
s
[
i
]
->
dl_algo
.
data
);
}
// the following block is meant for validation of the pre-processor to check
// whether all UE allocations are non-overlapping and is not necessary for
// scheduling functionality
char
t
[
26
]
=
"_________________________"
;
t
[
N_RBG
]
=
0
;
for
(
int
i
=
0
;
i
<
N_RBG
;
i
++
)
for
(
int
j
=
0
;
j
<
RBGsize
;
j
++
)
if
(
vrb_map
[
RBGsize
*
i
+
j
]
!=
0
)
t
[
i
]
=
'x'
;
int
print
=
0
;
for
(
int
UE_id
=
UE_info
->
list
.
head
;
UE_id
>=
0
;
UE_id
=
UE_info
->
list
.
next
[
UE_id
])
{
const
UE_sched_ctrl_t
*
ue_sched_ctrl
=
&
UE_info
->
UE_sched_ctrl
[
UE_id
];
if
(
ue_sched_ctrl
->
pre_nb_available_rbs
[
CC_id
]
==
0
)
continue
;
LOG_D
(
MAC
,
"%4d.%d UE%d %d RBs allocated, pre MCS %d
\n
"
,
frame
,
subframe
,
UE_id
,
ue_sched_ctrl
->
pre_nb_available_rbs
[
CC_id
],
UE_info
->
eNB_UE_stats
[
CC_id
][
UE_id
].
dlsch_mcs1
);
print
=
1
;
for
(
int
i
=
0
;
i
<
N_RBG
;
i
++
)
{
if
(
!
ue_sched_ctrl
->
rballoc_sub_UE
[
CC_id
][
i
])
continue
;
for
(
int
j
=
0
;
j
<
RBGsize
;
j
++
)
{
if
(
vrb_map
[
RBGsize
*
i
+
j
]
!=
0
)
{
LOG_I
(
MAC
,
"%4d.%d DL scheduler allocation list: %s
\n
"
,
frame
,
subframe
,
t
);
LOG_E
(
MAC
,
"%4d.%d: UE %d allocated at locked RB %d/RBG %d
\n
"
,
frame
,
subframe
,
UE_id
,
RBGsize
*
i
+
j
,
i
);
}
vrb_map
[
RBGsize
*
i
+
j
]
=
1
;
}
t
[
i
]
=
'0'
+
UE_id
;
}
}
if
(
print
)
LOG_D
(
MAC
,
"%4d.%d DL scheduler allocation list: %s
\n
"
,
frame
,
subframe
,
t
);
}
void
static_ul
(
module_id_t
mod_id
,
int
CC_id
,
frame_t
frame
,
sub_frame_t
subframe
,
frame_t
sched_frame
,
sub_frame_t
sched_subframe
)
{
UE_info_t
*
UE_info
=
&
RC
.
mac
[
mod_id
]
->
UE_info
;
const
int
N_RB_UL
=
to_prb
(
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
].
ul_Bandwidth
);
COMMON_channels_t
*
cc
=
&
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
];
for
(
int
UE_id
=
UE_info
->
list
.
head
;
UE_id
>=
0
;
UE_id
=
UE_info
->
list
.
next
[
UE_id
])
{
UE_TEMPLATE
*
UE_template
=
&
UE_info
->
UE_template
[
CC_id
][
UE_id
];
UE_template
->
pre_assigned_mcs_ul
=
0
;
UE_template
->
pre_allocated_nb_rb_ul
=
0
;
UE_template
->
pre_allocated_rb_table_index_ul
=
-
1
;
UE_template
->
pre_first_nb_rb_ul
=
0
;
UE_template
->
pre_dci_ul_pdu_idx
=
-
1
;
}
slice_info_t
*
s
=
RC
.
mac
[
mod_id
]
->
pre_processor_ul
.
slices
;
int
max_num_ue
;
switch
(
s
->
num
)
{
case
1
:
max_num_ue
=
4
;
break
;
case
2
:
max_num_ue
=
2
;
break
;
default:
max_num_ue
=
1
;
break
;
}
for
(
int
i
=
0
;
i
<
s
->
num
;
++
i
)
{
if
(
s
->
s
[
i
]
->
UEs
.
head
<
0
)
continue
;
int
last_rb_blocked
=
1
;
int
n_contig
=
0
;
contig_rbs_t
rbs
[
2
];
// up to two contig RBs for PRACH in between
static_slice_param_t
*
p
=
s
->
s
[
i
]
->
algo_data
;
for
(
int
rb
=
p
->
posLow
;
rb
<=
p
->
posHigh
&&
rb
<
N_RB_UL
;
++
rb
)
{
if
(
cc
->
vrb_map_UL
[
rb
]
==
0
&&
last_rb_blocked
)
{
last_rb_blocked
=
0
;
n_contig
++
;
AssertFatal
(
n_contig
<=
2
,
"cannot handle more than two contiguous RB regions
\n
"
);
rbs
[
n_contig
-
1
].
start
=
rb
;
}
if
(
cc
->
vrb_map_UL
[
rb
]
==
1
&&
!
last_rb_blocked
)
{
last_rb_blocked
=
1
;
rbs
[
n_contig
-
1
].
length
=
rb
-
rbs
[
n_contig
-
1
].
start
;
}
}
if
(
!
last_rb_blocked
)
rbs
[
n_contig
-
1
].
length
=
p
->
posHigh
-
rbs
[
n_contig
-
1
].
start
+
1
;
s
->
s
[
i
]
->
ul_algo
.
run
(
mod_id
,
CC_id
,
frame
,
subframe
,
sched_frame
,
sched_subframe
,
&
s
->
s
[
i
]
->
UEs
,
max_num_ue
,
// max_num_ue
n_contig
,
rbs
,
s
->
s
[
i
]
->
ul_algo
.
data
);
}
// the following block is meant for validation of the pre-processor to check
// whether all UE allocations are non-overlapping and is not necessary for
// scheduling functionality
char
t
[
101
]
=
"__________________________________________________"
"__________________________________________________"
;
t
[
N_RB_UL
]
=
0
;
for
(
int
j
=
0
;
j
<
N_RB_UL
;
j
++
)
if
(
cc
->
vrb_map_UL
[
j
]
!=
0
)
t
[
j
]
=
'x'
;
int
print
=
0
;
for
(
int
UE_id
=
UE_info
->
list
.
head
;
UE_id
>=
0
;
UE_id
=
UE_info
->
list
.
next
[
UE_id
])
{
UE_TEMPLATE
*
UE_template
=
&
UE_info
->
UE_template
[
CC_id
][
UE_id
];
if
(
UE_template
->
pre_allocated_nb_rb_ul
==
0
)
continue
;
print
=
1
;
uint8_t
harq_pid
=
subframe2harqpid
(
&
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
],
sched_frame
,
sched_subframe
);
LOG_D
(
MAC
,
"%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s
\n
"
,
frame
,
subframe
,
UE_id
,
UE_template
->
pre_allocated_nb_rb_ul
,
UE_template
->
pre_allocated_rb_table_index_ul
,
UE_template
->
pre_first_nb_rb_ul
,
UE_template
->
pre_assigned_mcs_ul
,
UE_info
->
UE_sched_ctrl
[
UE_id
].
round_UL
[
CC_id
][
harq_pid
]
>
0
?
"(retx)"
:
""
);
for
(
int
i
=
0
;
i
<
UE_template
->
pre_allocated_nb_rb_ul
;
++
i
)
{
/* only check if this is not a retransmission */
if
(
UE_info
->
UE_sched_ctrl
[
UE_id
].
round_UL
[
CC_id
][
harq_pid
]
==
0
&&
cc
->
vrb_map_UL
[
UE_template
->
pre_first_nb_rb_ul
+
i
]
==
1
)
{
LOG_I
(
MAC
,
"%4d.%d UL scheduler allocation list: %s
\n
"
,
frame
,
subframe
,
t
);
LOG_E
(
MAC
,
"%4d.%d: UE %d allocated at locked RB %d (is: allocated start "
"%d/length %d)
\n
"
,
frame
,
subframe
,
UE_id
,
UE_template
->
pre_first_nb_rb_ul
+
i
,
UE_template
->
pre_first_nb_rb_ul
,
UE_template
->
pre_allocated_nb_rb_ul
);
}
cc
->
vrb_map_UL
[
UE_template
->
pre_first_nb_rb_ul
+
i
]
=
1
;
t
[
UE_template
->
pre_first_nb_rb_ul
+
i
]
=
UE_id
+
'0'
;
}
}
if
(
print
)
LOG_D
(
MAC
,
"%4d.%d UL scheduler allocation list: %s
\n
"
,
sched_frame
,
sched_subframe
,
t
);
}
void
static_destroy
(
slice_info_t
**
si
)
{
const
int
n
=
(
*
si
)
->
num
;
(
*
si
)
->
num
=
0
;
for
(
int
i
=
0
;
i
<
n
;
++
i
)
{
slice_t
*
s
=
(
*
si
)
->
s
[
i
];
if
(
s
->
label
)
free
(
s
->
label
);
free
(
s
->
algo_data
);
free
(
s
);
}
free
((
*
si
)
->
s
);
free
(
*
si
);
}
pp_impl_param_t
static_dl_init
(
module_id_t
mod_id
,
int
CC_id
)
{
slice_info_t
*
si
=
calloc
(
1
,
sizeof
(
slice_info_t
));
DevAssert
(
si
);
si
->
num
=
0
;
si
->
s
=
calloc
(
MAX_STATIC_SLICES
,
sizeof
(
slice_t
));
DevAssert
(
si
->
s
);
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_ENB
;
++
i
)
si
->
UE_assoc_slice
[
i
]
=
-
1
;
/* insert default slice, all resources */
static_slice_param_t
*
dlp
=
malloc
(
sizeof
(
static_slice_param_t
));
dlp
->
posLow
=
0
;
dlp
->
posHigh
=
to_rbg
(
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
].
mib
->
message
.
dl_Bandwidth
)
-
1
;
default_sched_dl_algo_t
*
algo
=
&
RC
.
mac
[
mod_id
]
->
pre_processor_dl
.
dl_algo
;
DevAssert
(
0
==
addmod_static_slice_dl
(
si
,
0
,
strdup
(
"default"
),
algo
,
dlp
));
const
UE_list_t
*
UE_list
=
&
RC
.
mac
[
mod_id
]
->
UE_info
.
list
;
for
(
int
UE_id
=
UE_list
->
head
;
UE_id
>=
0
;
UE_id
=
UE_list
->
next
[
UE_id
])
slicing_add_UE
(
si
,
UE_id
);
pp_impl_param_t
sttc
;
sttc
.
algorithm
=
STATIC_SLICING
;
sttc
.
add_UE
=
slicing_add_UE
;
sttc
.
remove_UE
=
slicing_remove_UE
;
sttc
.
move_UE
=
slicing_move_UE
;
sttc
.
addmod_slice
=
addmod_static_slice_dl
;
sttc
.
remove_slice
=
remove_static_slice
;
sttc
.
dl
=
static_dl
;
// current DL algo becomes default scheduler
sttc
.
dl_algo
=
*
algo
;
sttc
.
destroy
=
static_destroy
;
sttc
.
slices
=
si
;
return
sttc
;
}
pp_impl_param_t
static_ul_init
(
module_id_t
mod_id
,
int
CC_id
)
{
slice_info_t
*
si
=
calloc
(
1
,
sizeof
(
slice_info_t
));
DevAssert
(
si
);
si
->
num
=
0
;
si
->
s
=
calloc
(
MAX_STATIC_SLICES
,
sizeof
(
slice_t
));
DevAssert
(
si
->
s
);
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_ENB
;
++
i
)
si
->
UE_assoc_slice
[
i
]
=
-
1
;
/* insert default slice, all resources */
static_slice_param_t
*
ulp
=
malloc
(
sizeof
(
static_slice_param_t
));
ulp
->
posLow
=
0
;
ulp
->
posHigh
=
to_prb
(
RC
.
mac
[
mod_id
]
->
common_channels
[
CC_id
].
ul_Bandwidth
)
-
1
;
default_sched_ul_algo_t
*
algo
=
&
RC
.
mac
[
mod_id
]
->
pre_processor_ul
.
ul_algo
;
DevAssert
(
0
==
addmod_static_slice_ul
(
si
,
0
,
strdup
(
"default"
),
algo
,
ulp
));
const
UE_list_t
*
UE_list
=
&
RC
.
mac
[
mod_id
]
->
UE_info
.
list
;
for
(
int
UE_id
=
UE_list
->
head
;
UE_id
>=
0
;
UE_id
=
UE_list
->
next
[
UE_id
])
slicing_add_UE
(
si
,
UE_id
);
pp_impl_param_t
sttc
;
sttc
.
algorithm
=
STATIC_SLICING
;
sttc
.
add_UE
=
slicing_add_UE
;
sttc
.
remove_UE
=
slicing_remove_UE
;
sttc
.
move_UE
=
slicing_move_UE
;
sttc
.
addmod_slice
=
addmod_static_slice_ul
;
sttc
.
remove_slice
=
remove_static_slice
;
sttc
.
ul
=
static_ul
;
// current DL algo becomes default scheduler
sttc
.
ul_algo
=
*
algo
;
sttc
.
destroy
=
static_destroy
;
sttc
.
slices
=
si
;
return
sttc
;
}
openair2/LAYER2/MAC/slicing/slicing.h
0 → 100644
View file @
872cfc03
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*!
* \file slicing.h
* \brief General slice definition and helper parameters
* \author Robert Schmidt
* \date 2020
* \email robert.schmidt@eurecom.fr
*/
#ifndef __SLICING_H__
#define __SLICING_H__
#include "openair2/LAYER2/MAC/mac.h"
typedef
struct
slice_s
{
/// Arbitrary ID
slice_id_t
id
;
/// Arbitrary label
char
*
label
;
union
{
default_sched_dl_algo_t
dl_algo
;
default_sched_ul_algo_t
ul_algo
;
};
/// A specific algorithm's implementation parameters
void
*
algo_data
;
/// Internal data that might be kept alongside a slice's params
void
*
int_data
;
// list of users in this slice
UE_list_t
UEs
;
}
slice_t
;
typedef
struct
slice_info_s
{
uint8_t
num
;
slice_t
**
s
;
uint8_t
UE_assoc_slice
[
MAX_MOBILES_PER_ENB
];
}
slice_info_t
;
int
slicing_get_UE_slice_idx
(
slice_info_t
*
si
,
int
UE_id
);
#define STATIC_SLICING 10
/* only four static slices for UL, DL resp. (not enough DCIs) */
#define MAX_STATIC_SLICES 4
typedef
struct
{
uint16_t
posLow
;
uint16_t
posHigh
;
}
static_slice_param_t
;
pp_impl_param_t
static_dl_init
(
module_id_t
mod_id
,
int
CC_id
);
pp_impl_param_t
static_ul_init
(
module_id_t
mod_id
,
int
CC_id
);
#endif
/* __SLICING_H__ */
openair2/LAYER2/MAC/slicing/slicing_internal.h
0 → 100644
View file @
872cfc03
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*!
* \file slicing_internal.h
* \brief Internal slice helper functions
* \author Robert Schmidt
* \date 2020
* \email robert.schmidt@eurecom.fr
*/
#ifndef __SLICING_INTERNAL_H__
#define __SLICING_INTERNAL_H__
#include "slicing.h"
void
slicing_add_UE
(
slice_info_t
*
si
,
int
UE_id
);
void
_remove_UE
(
slice_t
**
s
,
uint8_t
*
assoc
,
int
UE_id
);
void
slicing_remove_UE
(
slice_info_t
*
si
,
int
UE_id
);
void
_move_UE
(
slice_t
**
s
,
uint8_t
*
assoc
,
int
UE_id
,
int
to
);
void
slicing_move_UE
(
slice_info_t
*
si
,
int
UE_id
,
int
idx
);
slice_t
*
_add_slice
(
uint8_t
*
n
,
slice_t
**
s
);
slice_t
*
_remove_slice
(
uint8_t
*
n
,
slice_t
**
s
,
uint8_t
*
assoc
,
int
idx
);
#endif
/* __SLICING_INTERNAL_H__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment